70#include "llvm/IR/IntrinsicsPowerPC.h"
105#define DEBUG_TYPE "ppc-lowering"
127 cl::desc(
"disable vector permute decomposition"),
131 "disable-auto-paired-vec-st",
132 cl::desc(
"disable automatically generated 32byte paired vector stores"),
138 "Number of shuffles lowered to a VPERM or XXPERM");
139STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
156 initializeAddrModeMap();
159 bool isPPC64 = Subtarget.
isPPC64();
168 if (!Subtarget.hasEFPU2())
193 if (Subtarget.isISA3_0()) {
223 if (!Subtarget.hasSPE()) {
231 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
232 for (
MVT VT : ScalarIntVTs) {
239 if (Subtarget.useCRBits()) {
242 if (isPPC64 || Subtarget.hasFPCVT()) {
245 isPPC64 ? MVT::i64 : MVT::i32);
248 isPPC64 ? MVT::i64 : MVT::i32);
252 isPPC64 ? MVT::i64 : MVT::i32);
255 isPPC64 ? MVT::i64 : MVT::i32);
259 isPPC64 ? MVT::i64 : MVT::i32);
262 isPPC64 ? MVT::i64 : MVT::i32);
266 isPPC64 ? MVT::i64 : MVT::i32);
269 isPPC64 ? MVT::i64 : MVT::i32);
316 if (Subtarget.isISA3_0()) {
351 if (!Subtarget.hasSPE()) {
356 if (Subtarget.hasVSX()) {
361 if (Subtarget.hasFSQRT()) {
366 if (Subtarget.hasFPRND()) {
407 if (Subtarget.hasSPE()) {
415 if (Subtarget.hasSPE())
421 if (!Subtarget.hasFSQRT() &&
422 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
426 if (!Subtarget.hasFSQRT() &&
427 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
428 Subtarget.hasFRES()))
431 if (Subtarget.hasFCPSGN()) {
439 if (Subtarget.hasFPRND()) {
453 if (Subtarget.isISA3_1()) {
464 if (Subtarget.isISA3_0()) {
484 if (!Subtarget.useCRBits()) {
497 if (!Subtarget.useCRBits())
500 if (Subtarget.hasFPU()) {
511 if (!Subtarget.useCRBits())
516 if (Subtarget.hasSPE()) {
540 if (Subtarget.hasDirectMove() && isPPC64) {
545 if (
TM.Options.UnsafeFPMath) {
648 if (Subtarget.hasSPE()) {
670 if (Subtarget.has64BitSupport()) {
685 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
691 if (Subtarget.hasSPE()) {
701 if (Subtarget.hasFPCVT()) {
702 if (Subtarget.has64BitSupport()) {
723 if (Subtarget.use64BitRegs()) {
741 if (Subtarget.has64BitSupport()) {
748 if (Subtarget.hasVSX()) {
755 if (Subtarget.hasAltivec()) {
756 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
771 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
784 if (Subtarget.hasVSX()) {
790 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
800 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
874 if (!Subtarget.hasP8Vector()) {
916 if (Subtarget.hasAltivec())
917 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
920 if (Subtarget.hasP8Altivec())
931 if (Subtarget.hasVSX()) {
937 if (Subtarget.hasP8Altivec())
942 if (Subtarget.isISA3_1()) {
980 if (Subtarget.hasVSX()) {
983 if (Subtarget.hasP8Vector()) {
987 if (Subtarget.hasDirectMove() && isPPC64) {
1001 if (
TM.Options.UnsafeFPMath) {
1038 if (Subtarget.hasP8Vector())
1047 if (Subtarget.hasP8Altivec()) {
1074 if (Subtarget.isISA3_1())
1176 if (Subtarget.hasP8Altivec()) {
1181 if (Subtarget.hasP9Vector()) {
1186 if (Subtarget.useCRBits()) {
1245 }
else if (Subtarget.hasVSX()) {
1270 for (
MVT VT : {MVT::f32, MVT::f64}) {
1289 if (Subtarget.hasP9Altivec()) {
1290 if (Subtarget.isISA3_1()) {
1313 if (Subtarget.hasP10Vector()) {
1318 if (Subtarget.pairedVectorMemops()) {
1323 if (Subtarget.hasMMA()) {
1324 if (Subtarget.isISAFuture())
1333 if (Subtarget.has64BitSupport())
1336 if (Subtarget.isISA3_1())
1354 if (Subtarget.hasAltivec()) {
1381 if (Subtarget.hasFPCVT())
1384 if (Subtarget.useCRBits())
1393 if (Subtarget.useCRBits()) {
1422 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1423 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1424 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1425 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1430 if (Subtarget.useCRBits()) {
1527void PPCTargetLowering::initializeAddrModeMap() {
1578 if (MaxAlign == MaxMaxAlign)
1581 if (MaxMaxAlign >= 32 &&
1582 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1583 MaxAlign =
Align(32);
1584 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1586 MaxAlign =
Align(16);
1590 if (EltAlign > MaxAlign)
1591 MaxAlign = EltAlign;
1593 for (
auto *EltTy : STy->elements()) {
1596 if (EltAlign > MaxAlign)
1597 MaxAlign = EltAlign;
1598 if (MaxAlign == MaxMaxAlign)
1611 if (Subtarget.hasAltivec())
1613 return Alignment.
value();
1621 return Subtarget.hasSPE();
1645 return "PPCISD::FTSQRT";
1647 return "PPCISD::FSQRT";
1652 return "PPCISD::XXSPLTI_SP_TO_DP";
1654 return "PPCISD::XXSPLTI32DX";
1658 return "PPCISD::XXPERM";
1678 return "PPCISD::CALL_RM";
1680 return "PPCISD::CALL_NOP_RM";
1682 return "PPCISD::CALL_NOTOC_RM";
1687 return "PPCISD::BCTRL_RM";
1689 return "PPCISD::BCTRL_LOAD_TOC_RM";
1701 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1703 return "PPCISD::ANDI_rec_1_EQ_BIT";
1705 return "PPCISD::ANDI_rec_1_GT_BIT";
1720 return "PPCISD::ST_VSR_SCAL_INT";
1747 return "PPCISD::PADDI_DTPREL";
1763 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1765 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1775 return "PPCISD::STRICT_FADDRTZ";
1777 return "PPCISD::STRICT_FCTIDZ";
1779 return "PPCISD::STRICT_FCTIWZ";
1781 return "PPCISD::STRICT_FCTIDUZ";
1783 return "PPCISD::STRICT_FCTIWUZ";
1785 return "PPCISD::STRICT_FCFID";
1787 return "PPCISD::STRICT_FCFIDU";
1789 return "PPCISD::STRICT_FCFIDS";
1791 return "PPCISD::STRICT_FCFIDUS";
1794 return "PPCISD::STORE_COND";
1802 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1819 return CFP->getValueAPF().isZero();
1824 return CFP->getValueAPF().isZero();
1832 return Op < 0 ||
Op == Val;
1844 if (ShuffleKind == 0) {
1847 for (
unsigned i = 0; i != 16; ++i)
1850 }
else if (ShuffleKind == 2) {
1853 for (
unsigned i = 0; i != 16; ++i)
1856 }
else if (ShuffleKind == 1) {
1857 unsigned j = IsLE ? 0 : 1;
1858 for (
unsigned i = 0; i != 8; ++i)
1875 if (ShuffleKind == 0) {
1878 for (
unsigned i = 0; i != 16; i += 2)
1882 }
else if (ShuffleKind == 2) {
1885 for (
unsigned i = 0; i != 16; i += 2)
1889 }
else if (ShuffleKind == 1) {
1890 unsigned j = IsLE ? 0 : 2;
1891 for (
unsigned i = 0; i != 8; i += 2)
1912 if (!Subtarget.hasP8Vector())
1916 if (ShuffleKind == 0) {
1919 for (
unsigned i = 0; i != 16; i += 4)
1925 }
else if (ShuffleKind == 2) {
1928 for (
unsigned i = 0; i != 16; i += 4)
1934 }
else if (ShuffleKind == 1) {
1935 unsigned j = IsLE ? 0 : 4;
1936 for (
unsigned i = 0; i != 8; i += 4)
1953 unsigned LHSStart,
unsigned RHSStart) {
1954 if (
N->getValueType(0) != MVT::v16i8)
1956 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1957 "Unsupported merge size!");
1959 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1960 for (
unsigned j = 0; j != UnitSize; ++j) {
1962 LHSStart+j+i*UnitSize) ||
1964 RHSStart+j+i*UnitSize))
1979 if (ShuffleKind == 1)
1981 else if (ShuffleKind == 2)
1986 if (ShuffleKind == 1)
1988 else if (ShuffleKind == 0)
2004 if (ShuffleKind == 1)
2006 else if (ShuffleKind == 2)
2011 if (ShuffleKind == 1)
2013 else if (ShuffleKind == 0)
2063 unsigned RHSStartValue) {
2064 if (
N->getValueType(0) != MVT::v16i8)
2067 for (
unsigned i = 0; i < 2; ++i)
2068 for (
unsigned j = 0; j < 4; ++j)
2070 i*RHSStartValue+j+IndexOffset) ||
2072 i*RHSStartValue+j+IndexOffset+8))
2094 unsigned indexOffset = CheckEven ? 4 : 0;
2095 if (ShuffleKind == 1)
2097 else if (ShuffleKind == 2)
2103 unsigned indexOffset = CheckEven ? 0 : 4;
2104 if (ShuffleKind == 1)
2106 else if (ShuffleKind == 0)
2122 if (
N->getValueType(0) != MVT::v16i8)
2129 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2132 if (i == 16)
return -1;
2137 if (ShiftAmt < i)
return -1;
2142 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2144 for (++i; i != 16; ++i)
2147 }
else if (ShuffleKind == 1) {
2149 for (++i; i != 16; ++i)
2156 ShiftAmt = 16 - ShiftAmt;
2165 EVT VT =
N->getValueType(0);
2166 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2167 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2170 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2174 if (
N->getMaskElt(0) % EltSize != 0)
2179 unsigned ElementBase =
N->getMaskElt(0);
2182 if (ElementBase >= 16)
2187 for (
unsigned i = 1; i != EltSize; ++i)
2188 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2191 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2192 if (
N->getMaskElt(i) < 0)
continue;
2193 for (
unsigned j = 0; j != EltSize; ++j)
2194 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2211 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2212 "Unexpected element width.");
2213 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2215 unsigned NumOfElem = 16 / Width;
2216 unsigned MaskVal[16];
2217 for (
unsigned i = 0; i < NumOfElem; ++i) {
2218 MaskVal[0] =
N->getMaskElt(i * Width);
2219 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2221 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2225 for (
unsigned int j = 1; j < Width; ++j) {
2226 MaskVal[j] =
N->getMaskElt(i * Width + j);
2227 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2237 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2242 unsigned M0 =
N->getMaskElt(0) / 4;
2243 unsigned M1 =
N->getMaskElt(4) / 4;
2244 unsigned M2 =
N->getMaskElt(8) / 4;
2245 unsigned M3 =
N->getMaskElt(12) / 4;
2246 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2247 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2252 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2253 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2254 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2255 InsertAtByte = IsLE ? 12 : 0;
2260 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2261 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2262 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2263 InsertAtByte = IsLE ? 8 : 4;
2268 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2269 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2270 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2271 InsertAtByte = IsLE ? 4 : 8;
2276 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2277 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2278 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2279 InsertAtByte = IsLE ? 0 : 12;
2286 if (
N->getOperand(1).isUndef()) {
2289 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2290 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2291 InsertAtByte = IsLE ? 12 : 0;
2294 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2295 InsertAtByte = IsLE ? 8 : 4;
2298 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2299 InsertAtByte = IsLE ? 4 : 8;
2302 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2303 InsertAtByte = IsLE ? 0 : 12;
2312 bool &Swap,
bool IsLE) {
2313 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2319 unsigned M0 =
N->getMaskElt(0) / 4;
2320 unsigned M1 =
N->getMaskElt(4) / 4;
2321 unsigned M2 =
N->getMaskElt(8) / 4;
2322 unsigned M3 =
N->getMaskElt(12) / 4;
2326 if (
N->getOperand(1).isUndef()) {
2327 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2328 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2331 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2337 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2341 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2346 ShiftElts = (8 -
M0) % 8;
2347 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2352 ShiftElts = (4 -
M0) % 4;
2357 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2362 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2374 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2379 for (
int i = 0; i < 16; i += Width)
2380 if (
N->getMaskElt(i) != i + Width - 1)
2411 bool &Swap,
bool IsLE) {
2412 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2418 unsigned M0 =
N->getMaskElt(0) / 8;
2419 unsigned M1 =
N->getMaskElt(8) / 8;
2420 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2424 if (
N->getOperand(1).isUndef()) {
2425 if ((
M0 |
M1) < 2) {
2426 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2434 if (
M0 > 1 &&
M1 < 2) {
2444 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2449 }
else if (
M0 > 1 &&
M1 < 2) {
2457 DM = (
M0 << 1) + (
M1 & 1);
2472 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2477 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2494 if (EltSize < ByteSize) {
2495 unsigned Multiple = ByteSize/EltSize;
2497 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2500 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2501 if (
N->getOperand(i).isUndef())
continue;
2505 if (!UniquedVals[i&(Multiple-1)].getNode())
2507 else if (UniquedVals[i&(Multiple-1)] !=
N->
getOperand(i))
2517 bool LeadingZero =
true;
2518 bool LeadingOnes =
true;
2519 for (
unsigned i = 0; i != Multiple-1; ++i) {
2520 if (!UniquedVals[i].getNode())
continue;
2527 if (!UniquedVals[Multiple-1].getNode())
2534 if (!UniquedVals[Multiple-1].getNode())
2545 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2546 if (
N->getOperand(i).isUndef())
continue;
2555 unsigned ValSizeInBytes = EltSize;
2558 Value = CN->getZExtValue();
2560 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2567 if (ValSizeInBytes < ByteSize)
return SDValue();
2578 if (MaskVal == 0)
return SDValue();
2599 if (
N->getValueType(0) == MVT::i32)
2620 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2630 if (Memop->getMemoryVT() == MVT::f64) {
2631 Base =
N.getOperand(0);
2675 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2680 Base =
N.getOperand(0);
2683 }
else if (
N.getOpcode() ==
ISD::OR) {
2685 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2697 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2698 Base =
N.getOperand(0);
2769 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2775 Base =
N.getOperand(0);
2778 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2781 &&
"Cannot handle constant offsets yet!");
2787 Base =
N.getOperand(0);
2790 }
else if (
N.getOpcode() ==
ISD::OR) {
2793 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2807 Base =
N.getOperand(0);
2820 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2823 CN->getValueType(0));
2828 if ((CN->getValueType(0) == MVT::i32 ||
2829 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2830 (!EncodingAlignment ||
2831 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2832 int Addr = (int)CN->getZExtValue();
2839 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2860 if (
N.getValueType() != MVT::i64)
2922 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2923 Base =
N.getOperand(0);
2967 EVT MemVT = LD->getMemoryVT();
2974 if (!ST.hasP8Vector())
2979 if (!ST.hasP9Vector())
2992 if (UI.getUse().get().getResNo() == 0 &&
3014 Ptr = LD->getBasePtr();
3015 VT = LD->getMemoryVT();
3016 Alignment = LD->getAlign();
3018 Ptr = ST->getBasePtr();
3019 VT = ST->getMemoryVT();
3020 Alignment = ST->getAlign();
3059 if (VT != MVT::i64) {
3064 if (Alignment <
Align(4))
3074 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3091 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3133 const bool Is64Bit = Subtarget.
isPPC64();
3134 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3148 EVT PtrVT =
Op.getValueType();
3164 return getTOCEntry(DAG,
SDLoc(CP), GA);
3167 unsigned MOHiFlag, MOLoFlag;
3174 return getTOCEntry(DAG,
SDLoc(CP), GA);
3234 EVT PtrVT =
Op.getValueType();
3252 return getTOCEntry(DAG,
SDLoc(JT), GA);
3255 unsigned MOHiFlag, MOLoFlag;
3262 return getTOCEntry(DAG,
SDLoc(GA), GA);
3272 EVT PtrVT =
Op.getValueType();
3291 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3300 unsigned MOHiFlag, MOLoFlag;
3311 return LowerGlobalTLSAddressAIX(
Op, DAG);
3313 return LowerGlobalTLSAddressLinux(
Op, DAG);
3326 bool Is64Bit = Subtarget.
isPPC64();
3332 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3365 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3366 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3384 bool is64bit = Subtarget.
isPPC64();
3432 if (!
TM.isPositionIndependent())
3491 PtrVT, GOTPtr, TGA, TGA);
3493 PtrVT, TLSAddr, TGA);
3502 EVT PtrVT =
Op.getValueType();
3528 return getTOCEntry(DAG,
DL, GA);
3531 unsigned MOHiFlag, MOLoFlag;
3539 return getTOCEntry(DAG,
DL, GA);
3551 bool IsStrict =
Op->isStrictFPOpcode();
3554 SDValue LHS =
Op.getOperand(IsStrict ? 1 : 0);
3555 SDValue RHS =
Op.getOperand(IsStrict ? 2 : 1);
3557 EVT LHSVT = LHS.getValueType();
3561 if (LHSVT == MVT::f128) {
3562 assert(!Subtarget.hasP9Vector() &&
3563 "SETCC for f128 is already legal under Power9!");
3574 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3576 if (
Op.getValueType() == MVT::v2i64) {
3579 if (LHS.getValueType() == MVT::v2i64) {
3585 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, LHS),
3586 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, RHS),
CC);
3587 int ShuffV[] = {1, 0, 3, 2};
3592 dl, MVT::v4i32, Shuff, SetCC32));
3609 if (
C->isAllOnes() ||
C->isZero())
3619 EVT VT =
Op.getValueType();
3628 EVT VT =
Node->getValueType(0);
3642 if (VT == MVT::i64) {
3673 InChain = OverflowArea.
getValue(1);
3719 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3726 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3741 return Op.getOperand(0);
3748 assert((
Op.getOpcode() == ISD::INLINEASM ||
3749 Op.getOpcode() == ISD::INLINEASM_BR) &&
3750 "Expecting Inline ASM node.");
3760 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3780 for (; NumVals; --NumVals, ++i) {
3782 if (Reg != PPC::LR && Reg != PPC::LR8)
3807 bool isPPC64 = (PtrVT == MVT::i64);
3813 Entry.
Ty = IntPtrTy;
3814 Entry.Node = Trmp;
Args.push_back(Entry);
3817 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3818 isPPC64 ? MVT::i64 : MVT::i32);
3819 Args.push_back(Entry);
3821 Entry.Node = FPtr;
Args.push_back(Entry);
3822 Entry.Node = Nest;
Args.push_back(Entry);
3826 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3830 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3831 return CallResult.second;
3846 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3881 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3905 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3908 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3910 nextOffset += FrameOffset;
3911 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3914 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3920static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3921 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3922 PPC::F11, PPC::F12, PPC::F13};
3927 unsigned PtrByteSize) {
3929 if (Flags.isByVal())
3930 ArgSize = Flags.getByValSize();
3934 if (!Flags.isInConsecutiveRegs())
3935 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
3944 unsigned PtrByteSize) {
3945 Align Alignment(PtrByteSize);
3948 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
3949 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
3950 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
3951 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
3952 Alignment =
Align(16);
3955 if (Flags.isByVal()) {
3956 auto BVAlign = Flags.getNonZeroByValAlign();
3957 if (BVAlign > PtrByteSize) {
3958 if (BVAlign.value() % PtrByteSize != 0)
3960 "ByVal alignment is not a multiple of the pointer size");
3962 Alignment = BVAlign;
3967 if (Flags.isInConsecutiveRegs()) {
3971 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
3985 unsigned PtrByteSize,
unsigned LinkageSize,
3986 unsigned ParamAreaSize,
unsigned &ArgOffset,
3987 unsigned &AvailableFPRs,
3988 unsigned &AvailableVRs) {
3989 bool UseMemory =
false;
3994 ArgOffset =
alignTo(ArgOffset, Alignment);
3997 if (ArgOffset >= LinkageSize + ParamAreaSize)
4002 if (Flags.isInConsecutiveRegsLast())
4003 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4006 if (ArgOffset > LinkageSize + ParamAreaSize)
4011 if (!Flags.isByVal()) {
4012 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4013 if (AvailableFPRs > 0) {
4017 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4018 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4019 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4020 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4021 if (AvailableVRs > 0) {
4033 unsigned NumBytes) {
4037SDValue PPCTargetLowering::LowerFormalArguments(
4038 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4042 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4045 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4048 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4052SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4053 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4094 const Align PtrAlign(4);
4103 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4105 CCInfo.PreAnalyzeFormalArguments(Ins);
4108 CCInfo.clearWasPPCF128();
4110 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4123 RC = &PPC::GPRCRegClass;
4126 if (Subtarget.hasP8Vector())
4127 RC = &PPC::VSSRCRegClass;
4128 else if (Subtarget.hasSPE())
4129 RC = &PPC::GPRCRegClass;
4131 RC = &PPC::F4RCRegClass;
4134 if (Subtarget.hasVSX())
4135 RC = &PPC::VSFRCRegClass;
4136 else if (Subtarget.hasSPE())
4138 RC = &PPC::GPRCRegClass;
4140 RC = &PPC::F8RCRegClass;
4145 RC = &PPC::VRRCRegClass;
4148 RC = &PPC::VRRCRegClass;
4152 RC = &PPC::VRRCRegClass;
4159 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4160 assert(i + 1 < e &&
"No second half of double precision argument");
4172 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4173 if (ValVT == MVT::i1)
4188 ArgOffset += ArgSize - ObjSize;
4206 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4211 unsigned MinReservedArea = CCByValInfo.getStackSize();
4212 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4228 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4229 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4231 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4234 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4237 unsigned NumFPArgRegs = std::size(FPArgRegs);
4246 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4250 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4259 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4263 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4278 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4282 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4295 if (!MemOps.
empty())
4306 const SDLoc &dl)
const {
4310 else if (Flags.isZExt())
4317SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4318 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
4330 "fastcc not supported on varargs functions");
4336 unsigned PtrByteSize = 8;
4340 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4341 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4344 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4345 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4348 const unsigned Num_GPR_Regs = std::size(GPR);
4350 const unsigned Num_VR_Regs = std::size(VR);
4358 bool HasParameterArea = !isELFv2ABI || isVarArg;
4359 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4360 unsigned NumBytes = LinkageSize;
4361 unsigned AvailableFPRs = Num_FPR_Regs;
4362 unsigned AvailableVRs = Num_VR_Regs;
4363 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4364 if (Ins[i].Flags.isNest())
4368 PtrByteSize, LinkageSize, ParamAreaSize,
4369 NumBytes, AvailableFPRs, AvailableVRs))
4370 HasParameterArea =
true;
4377 unsigned ArgOffset = LinkageSize;
4378 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4381 unsigned CurArgIdx = 0;
4382 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4384 bool needsLoad =
false;
4385 EVT ObjectVT =
Ins[ArgNo].VT;
4386 EVT OrigVT =
Ins[ArgNo].ArgVT;
4388 unsigned ArgSize = ObjSize;
4390 if (Ins[ArgNo].isOrigArg()) {
4391 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4392 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4397 unsigned CurArgOffset;
4399 auto ComputeArgOffset = [&]() {
4403 ArgOffset =
alignTo(ArgOffset, Alignment);
4404 CurArgOffset = ArgOffset;
4411 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4412 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4417 if (Flags.isByVal()) {
4418 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4424 ObjSize = Flags.getByValSize();
4425 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4447 if (HasParameterArea ||
4448 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4455 if (ObjSize < PtrByteSize) {
4459 if (!isLittleEndian) {
4465 if (GPR_idx != Num_GPR_Regs) {
4477 ArgOffset += PtrByteSize;
4486 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4487 if (GPR_idx == Num_GPR_Regs)
4498 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4506 ArgOffset += ArgSize;
4515 if (Flags.isNest()) {
4520 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4521 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4529 if (GPR_idx != Num_GPR_Regs) {
4534 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4537 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4543 ArgSize = PtrByteSize;
4554 if (FPR_idx != Num_FPR_Regs) {
4557 if (ObjectVT == MVT::f32)
4559 Subtarget.hasP8Vector()
4560 ? &PPC::VSSRCRegClass
4561 : &PPC::F4RCRegClass);
4564 ? &PPC::VSFRCRegClass
4565 : &PPC::F8RCRegClass);
4580 if (ObjectVT == MVT::f32) {
4581 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4587 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4599 ArgSize = Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4600 ArgOffset += ArgSize;
4601 if (Flags.isInConsecutiveRegsLast())
4602 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4616 if (VR_idx != Num_VR_Regs) {
4633 if (ObjSize < ArgSize && !isLittleEndian)
4634 CurArgOffset += ArgSize - ObjSize;
4644 unsigned MinReservedArea;
4645 if (HasParameterArea)
4646 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4648 MinReservedArea = LinkageSize;
4665 int Depth = ArgOffset;
4674 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4675 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4687 if (!MemOps.
empty())
4696 unsigned ParamSize) {
4698 if (!isTailCall)
return 0;
4702 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4704 if (SPDiff < FI->getTailCallSPDelta())
4720 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4733 if (!
TM.shouldAssumeDSOLocal(*Caller->getParent(), CalleeGV))
4778 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4779 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4782 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4794 const unsigned PtrByteSize = 8;
4798 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4799 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4802 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4803 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4806 const unsigned NumGPRs = std::size(GPR);
4807 const unsigned NumFPRs = 13;
4808 const unsigned NumVRs = std::size(VR);
4809 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4811 unsigned NumBytes = LinkageSize;
4812 unsigned AvailableFPRs = NumFPRs;
4813 unsigned AvailableVRs = NumVRs;
4816 if (Param.Flags.isNest())
continue;
4819 LinkageSize, ParamAreaSize, NumBytes,
4820 AvailableFPRs, AvailableVRs))
4831 auto CalleeArgEnd = CB.
arg_end();
4834 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4835 const Value* CalleeArg = *CalleeArgIter;
4836 const Value* CallerArg = &(*CallerArgIter);
4837 if (CalleeArg == CallerArg)
4858 CallingConv::ID CalleeCC) {
4860 auto isTailCallableCC = [] (CallingConv::ID
CC){
4863 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4873bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4874 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
4875 CallingConv::ID CallerCC,
const CallBase *CB,
bool isVarArg,
4878 bool isCalleeExternalSymbol)
const {
4881 if (
DisableSCO && !TailCallOpt)
return false;
4884 if (isVarArg)
return false;
4960bool PPCTargetLowering::IsEligibleForTailCallOptimization(
4961 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
4962 CallingConv::ID CallerCC,
bool isVarArg,
4994 if (!
C)
return nullptr;
4996 int Addr =
C->getZExtValue();
4997 if ((
Addr & 3) != 0 ||
5003 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5010struct TailCallArgumentInfo {
5015 TailCallArgumentInfo() =
default;
5025 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5027 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5028 int FI = TailCallArgs[i].FrameIdx;
5031 Chain, dl,
Arg, FIN,
5040 int SPDiff,
const SDLoc &dl) {
5046 bool isPPC64 = Subtarget.
isPPC64();
5047 int SlotSize = isPPC64 ? 8 : 4;
5048 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5050 NewRetAddrLoc,
true);
5051 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5053 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5065 int Offset = ArgOffset + SPDiff;
5066 uint32_t OpSize = (
Arg.getValueSizeInBits() + 7) / 8;
5068 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5070 TailCallArgumentInfo
Info;
5072 Info.FrameIdxOp = FIN;
5080SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5085 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5086 LROpOut = getReturnAddrFrameIndex(DAG);
5103 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5104 Flags.getNonZeroByValAlign(),
false,
false,
false,
5112 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5135 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5145 if (!MemOpChains2.
empty())
5169SDValue PPCTargetLowering::LowerCallResult(
5170 SDValue Chain,
SDValue InGlue, CallingConv::ID CallConv,
bool isVarArg,
5177 CCRetInfo.AnalyzeCallResult(
5183 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5189 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5267 bool IsStrictFPCall =
false) {
5271 unsigned RetOpc = 0;
5302 if (IsStrictFPCall) {
5333 auto isLocalCallee = [&]() {
5350 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5367 return getAIXFuncEntryPointSymbolSDNode(GV);
5374 const char *SymName = S->getSymbol();
5381 return getAIXFuncEntryPointSymbolSDNode(
F);
5387 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5395 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5408 "Expected a CALLSEQ_STARTSDNode.");
5426 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5467 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5482 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5487 Alignment, MMOFlags);
5494 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5501 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5513 "Nest parameter is not supported on AIX.");
5529 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5532 const bool IsPPC64 = Subtarget.
isPPC64();
5534 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5581 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5583 RegsToPass[i].second.getValueType()));
5600 assert(Mask &&
"Missing call preserved mask for calling convention");
5608SDValue PPCTargetLowering::FinishCall(
5623 if (!CFlags.IsIndirect)
5627 dl, CFlags.HasNest, Subtarget);
5637 if (CFlags.IsTailCall) {
5646 "Expecting a global address, external symbol, absolute value, "
5647 "register or an indirect tail call when PC Relative calls are "
5651 "Unexpected call opcode for a tail call.");
5658 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5659 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5671 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5674 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5694 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5695 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5699bool PPCTargetLowering::isEligibleForTCO(
5700 const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
5701 CallingConv::ID CallerCC,
const CallBase *CB,
bool isVarArg,
5704 bool isCalleeExternalSymbol)
const {
5709 return IsEligibleForTailCallOptimization_64SVR4(
5710 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5711 isCalleeExternalSymbol);
5713 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5728 CallingConv::ID CallConv = CLI.
CallConv;
5741 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5756 "Callee should be an llvm::Function object.");
5759 <<
"\nTCO callee: ");
5766 "site marked musttail");
5776 CallConv, isTailCall, isVarArg, isPatchPoint,
5784 return LowerCall_AIX(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5789 return LowerCall_64SVR4(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5791 return LowerCall_32SVR4(Chain,
Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5795SDValue PPCTargetLowering::LowerCall_32SVR4(
5805 const CallingConv::ID CallConv = CFlags.CallConv;
5806 const bool IsVarArg = CFlags.IsVarArg;
5807 const bool IsTailCall = CFlags.IsTailCall;
5813 const Align PtrAlign(4);
5838 CCInfo.PreAnalyzeCallOperands(Outs);
5844 unsigned NumArgs = Outs.
size();
5846 for (
unsigned i = 0; i != NumArgs; ++i) {
5847 MVT ArgVT = Outs[i].VT;
5851 if (Outs[i].IsFixed) {
5861 errs() <<
"Call operand #" << i <<
" has unhandled type "
5871 CCInfo.clearWasPPCF128();
5878 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5885 unsigned NumBytes = CCByValInfo.getStackSize();
5899 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5910 bool seenFloatArg =
false;
5915 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5917 ++i, ++RealArgIdx) {
5922 if (Flags.isByVal()) {
5927 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5950 Chain = CallSeqStart = NewCallSeqStart;
5962 if (
Arg.getValueType() == MVT::i1)
5969 if (Subtarget.hasSPE() &&
Arg.getValueType() == MVT::f64) {
5976 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6000 if (!MemOpChains.
empty())
6006 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6007 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6008 RegsToPass[i].second, InGlue);
6016 SDValue Ops[] = { Chain, InGlue };
6028 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6029 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6034SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6046 return NewCallSeqStart;
6049SDValue PPCTargetLowering::LowerCall_64SVR4(
6058 unsigned NumOps = Outs.
size();
6059 bool IsSibCall =
false;
6063 unsigned PtrByteSize = 8;
6078 assert(!(IsFastCall && CFlags.IsVarArg) &&
6079 "fastcc not supported on varargs functions");
6086 unsigned NumBytes = LinkageSize;
6087 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6090 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6091 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6094 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6095 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6098 const unsigned NumGPRs = std::size(GPR);
6100 const unsigned NumVRs = std::size(VR);
6106 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6107 if (!HasParameterArea) {
6108 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6109 unsigned AvailableFPRs = NumFPRs;
6110 unsigned AvailableVRs = NumVRs;
6111 unsigned NumBytesTmp = NumBytes;
6112 for (
unsigned i = 0; i != NumOps; ++i) {
6113 if (Outs[i].Flags.isNest())
continue;
6115 PtrByteSize, LinkageSize, ParamAreaSize,
6116 NumBytesTmp, AvailableFPRs, AvailableVRs))
6117 HasParameterArea =
true;
6123 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6128 HasParameterArea =
false;
6131 for (
unsigned i = 0; i != NumOps; ++i) {
6133 EVT ArgVT = Outs[i].VT;
6134 EVT OrigVT = Outs[i].ArgVT;
6140 if (Flags.isByVal()) {
6141 NumGPRsUsed += (Flags.getByValSize()+7)/8;
6142 if (NumGPRsUsed > NumGPRs)
6143 HasParameterArea =
true;
6150 if (++NumGPRsUsed <= NumGPRs)
6160 if (++NumVRsUsed <= NumVRs)
6164 if (++NumVRsUsed <= NumVRs)
6169 if (++NumFPRsUsed <= NumFPRs)
6173 HasParameterArea =
true;
6180 NumBytes =
alignTo(NumBytes, Alignement);
6183 if (Flags.isInConsecutiveRegsLast())
6184 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6187 unsigned NumBytesActuallyUsed = NumBytes;
6197 if (HasParameterArea)
6198 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6200 NumBytes = LinkageSize;
6215 if (CFlags.IsTailCall)
6227 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6238 unsigned ArgOffset = LinkageSize;
6244 for (
unsigned i = 0; i != NumOps; ++i) {
6247 EVT ArgVT = Outs[i].VT;
6248 EVT OrigVT = Outs[i].ArgVT;
6257 auto ComputePtrOff = [&]() {
6261 ArgOffset =
alignTo(ArgOffset, Alignment);
6272 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6273 GPR_idx = std::min(GPR_idx, NumGPRs);
6277 if (
Arg.getValueType() == MVT::i32 ||
Arg.getValueType() == MVT::i1) {
6286 if (Flags.isByVal()) {
6292 unsigned Size = Flags.getByValSize();
6305 if (GPR_idx != NumGPRs) {
6309 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6311 ArgOffset += PtrByteSize;
6316 if (GPR_idx == NumGPRs &&
Size < 8) {
6318 if (!isLittleEndian) {
6323 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6326 ArgOffset += PtrByteSize;
6335 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6336 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, PtrOff,
6341 if (
Size < 8 && GPR_idx != NumGPRs) {
6351 if (!isLittleEndian) {
6355 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
Arg, AddPtr,
6363 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6366 ArgOffset += PtrByteSize;
6372 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6375 if (GPR_idx != NumGPRs) {
6376 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6382 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6383 ArgOffset += PtrByteSize;
6385 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6392 switch (
Arg.getSimpleValueType().SimpleTy) {
6397 if (Flags.isNest()) {
6406 if (GPR_idx != NumGPRs) {
6407 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++],
Arg));
6412 assert(HasParameterArea &&
6413 "Parameter area must exist to pass an argument in memory.");
6415 true, CFlags.IsTailCall,
false, MemOpChains,
6416 TailCallArguments, dl);
6418 ArgOffset += PtrByteSize;
6421 ArgOffset += PtrByteSize;
6434 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6435 bool NeededLoad =
false;
6438 if (FPR_idx != NumFPRs)
6442 if (!NeedGPROrStack)
6444 else if (GPR_idx != NumGPRs && !IsFastCall) {
6454 if (
Arg.getValueType() != MVT::f32) {
6455 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64,
Arg);
6458 }
else if (!Flags.isInConsecutiveRegs()) {
6459 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32,
Arg);
6464 }
else if (ArgOffset % PtrByteSize != 0) {
6466 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6468 if (!isLittleEndian)
6473 }
else if (Flags.isInConsecutiveRegsLast()) {
6474 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32,
Arg);
6476 if (!isLittleEndian)
6486 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6493 if (
Arg.getValueType() == MVT::f32 &&
6494 !isLittleEndian && !Flags.isInConsecutiveRegs()) {
6499 assert(HasParameterArea &&
6500 "Parameter area must exist to pass an argument in memory.");
6502 true, CFlags.IsTailCall,
false, MemOpChains,
6503 TailCallArguments, dl);
6510 if (!IsFastCall || NeededLoad) {
6511 ArgOffset += (
Arg.getValueType() == MVT::f32 &&
6512 Flags.isInConsecutiveRegs()) ? 4 : 8;
6513 if (Flags.isInConsecutiveRegsLast())
6514 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6534 if (CFlags.IsVarArg) {
6535 assert(HasParameterArea &&
6536 "Parameter area must exist if we have a varargs call.");
6542 if (VR_idx != NumVRs) {
6546 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6549 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6550 if (GPR_idx == NumGPRs)
6557 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6563 if (VR_idx != NumVRs) {
6564 RegsToPass.
push_back(std::make_pair(VR[VR_idx++],
Arg));
6569 assert(HasParameterArea &&
6570 "Parameter area must exist to pass an argument in memory.");
6572 true, CFlags.IsTailCall,
true, MemOpChains,
6573 TailCallArguments, dl);
6584 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6585 "mismatch in size of parameter area");
6586 (void)NumBytesActuallyUsed;
6588 if (!MemOpChains.
empty())
6594 if (CFlags.IsIndirect) {
6598 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6613 if (isELFv2ABI && !CFlags.IsPatchPoint)
6620 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6621 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6622 RegsToPass[i].second, InGlue);
6626 if (CFlags.IsTailCall && !IsSibCall)
6630 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6631 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6638 "Required alignment greater than stack alignment.");
6658 return RequiredAlign <= 8;
6663 return RequiredAlign <= 4;
6672 State.getMachineFunction().getSubtarget());
6673 const bool IsPPC64 = Subtarget.
isPPC64();
6675 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6677 if (ValVT == MVT::f128)
6684 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6685 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6687 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6688 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6691 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6692 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6693 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6698 "register width are not supported.");
6704 if (ByValSize == 0) {
6706 State.getStackSize(), RegVT, LocInfo));
6710 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6711 unsigned Offset = State.AllocateStack(StackSize, PtrAlign);
6714 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6732 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6736 const unsigned Offset = State.AllocateStack(PtrAlign.
value(), PtrAlign);
6741 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6755 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6756 unsigned FReg = State.AllocateReg(
FPR);
6761 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6762 if (
unsigned Reg = State.AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6763 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6764 if (State.isVarArg()) {
6796 const unsigned VecSize = 16;
6797 const Align VecAlign(VecSize);
6799 if (!State.isVarArg()) {
6802 if (
unsigned VReg = State.AllocateReg(VR)) {
6809 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6814 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6817 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6820 while (NextRegIndex != GPRs.
size() &&
6823 unsigned Reg = State.AllocateReg(GPRs);
6824 State.AllocateStack(PtrSize, PtrAlign);
6825 assert(Reg &&
"Allocating register unexpectedly failed.");
6827 NextRegIndex = State.getFirstUnallocated(GPRs);
6834 if (State.isFixed(ValNo)) {
6835 if (
unsigned VReg = State.AllocateReg(VR)) {
6838 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6839 State.AllocateReg(GPRs);
6840 State.AllocateStack(VecSize, VecAlign);
6844 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6850 if (NextRegIndex == GPRs.
size()) {
6851 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6859 if (GPRs[NextRegIndex] == PPC::R9) {
6860 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6864 const unsigned FirstReg = State.AllocateReg(PPC::R9);
6865 const unsigned SecondReg = State.AllocateReg(PPC::R10);
6866 assert(FirstReg && SecondReg &&
6867 "Allocating R9 or R10 unexpectedly failed.");
6878 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6881 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6882 const unsigned Reg = State.AllocateReg(GPRs);
6883 assert(Reg &&
"Failed to allocated register for vararg vector argument");
6898 assert((IsPPC64 || SVT != MVT::i64) &&
6899 "i64 should have been split for 32-bit codegen.");
6907 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6909 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6911 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
6919 return &PPC::VRRCRegClass;
6932 else if (Flags.isZExt())
6942 if (PPC::GPRCRegClass.
contains(Reg)) {
6943 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
6944 "Reg must be a valid argument register!");
6945 return LASize + 4 * (Reg - PPC::R3);
6948 if (PPC::G8RCRegClass.
contains(Reg)) {
6949 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
6950 "Reg must be a valid argument register!");
6951 return LASize + 8 * (Reg - PPC::X3);
6997SDValue PPCTargetLowering::LowerFormalArguments_AIX(
6998 SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
7004 "Unexpected calling convention!");
7014 const bool IsPPC64 = Subtarget.
isPPC64();
7015 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7027 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7028 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7046 auto HandleMemLoc = [&]() {
7049 assert((ValSize <= LocSize) &&
7050 "Object size is larger than size of MemLoc");
7053 if (LocSize > ValSize)
7054 CurArgOffset += LocSize - ValSize;
7056 const bool IsImmutable =
7071 assert(isVarArg &&
"Only use custom memloc for vararg.");
7074 const unsigned OriginalValNo = VA.
getValNo();
7075 (void)OriginalValNo;
7077 auto HandleCustomVecRegLoc = [&]() {
7078 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7079 "Missing custom RegLoc.");
7082 "Unexpected Val type for custom RegLoc.");
7084 "ValNo mismatch between custom MemLoc and RegLoc.");
7088 Subtarget.hasVSX()));
7095 HandleCustomVecRegLoc();
7096 HandleCustomVecRegLoc();
7100 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7102 "Only 2 custom RegLocs expected for 64-bit codegen.");
7103 HandleCustomVecRegLoc();
7104 HandleCustomVecRegLoc();
7147 if (Flags.isByVal() && VA.
isMemLoc()) {
7148 const unsigned Size =
7149 alignTo(Flags.getByValSize() ? Flags.getByValSize() : PtrByteSize,
7160 if (Flags.isByVal()) {
7166 if (Flags.getNonZeroByValAlign() > PtrByteSize)
7169 const unsigned StackSize =
alignTo(Flags.getByValSize(), PtrByteSize);
7178 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7180 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7193 CopyFrom.
getValue(1), dl, CopyFrom,
7203 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7206 "RegLocs should be for ByVal argument.");
7213 if (
Offset != StackSize) {
7215 "Expected MemLoc for remaining bytes.");
7216 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7230 Subtarget.hasVSX()));
7247 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7249 unsigned CallerReservedArea = std::max<unsigned>(
7250 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7256 CallerReservedArea =
7265 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7266 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7268 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7269 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7270 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7275 for (
unsigned GPRIndex =
7276 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7277 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7280 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7281 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7293 if (!MemOps.
empty())
7299SDValue PPCTargetLowering::LowerCall_AIX(
7312 "Unexpected calling convention!");
7314 if (CFlags.IsPatchPoint)
7321 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7329 const bool IsPPC64 = Subtarget.
isPPC64();
7331 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7332 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7333 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7341 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7342 const unsigned NumBytes = std::max<unsigned>(
7343 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7359 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7360 const unsigned ValNo = ArgLocs[
I].getValNo();
7364 if (Flags.isByVal()) {
7365 const unsigned ByValSize = Flags.getByValSize();
7373 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7382 unsigned LoadOffset = 0;
7385 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7388 LoadOffset += PtrByteSize;
7391 "Unexpected location for pass-by-value argument.");
7395 if (LoadOffset == ByValSize)
7399 assert(ArgLocs[
I].getValNo() == ValNo &&
7400 "Expected additional location for by-value argument.");
7402 if (ArgLocs[
I].isMemLoc()) {
7403 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7408 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7414 CallSeqStart, MemcpyFlags, DAG, dl);
7423 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7424 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7425 "Unexpected register residue for by-value argument.");
7427 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7431 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7441 "Unexpected load emitted during handling of pass-by-value "
7449 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7484 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7492 const unsigned OriginalValNo = VA.
getValNo();
7494 unsigned LoadOffset = 0;
7495 auto HandleCustomVecRegLoc = [&]() {
7496 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7497 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7498 "Expected custom RegLoc.");
7501 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7507 LoadOffset += PtrByteSize;
7513 HandleCustomVecRegLoc();
7514 HandleCustomVecRegLoc();
7516 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7517 ArgLocs[
I].getValNo() == OriginalValNo) {
7519 "Only 2 custom RegLocs expected for 64-bit codegen.");
7520 HandleCustomVecRegLoc();
7521 HandleCustomVecRegLoc();
7539 "Unexpected register handling for calling convention.");
7545 "Custom register handling only expected for VarArg.");
7554 else if (
Arg.getValueType().getFixedSizeInBits() <
7562 assert(
Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7563 "Unexpected custom register for argument!");
7584 if (!MemOpChains.
empty())
7589 if (CFlags.IsIndirect) {
7590 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7593 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7594 const unsigned TOCSaveOffset =
7610 for (
auto Reg : RegsToPass) {
7611 Chain = DAG.
getCopyToReg(Chain, dl, Reg.first, Reg.second, InGlue);
7615 const int SPDiff = 0;
7616 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7617 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7621PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
7626 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7627 return CCInfo.CheckReturn(
7634PPCTargetLowering::LowerReturn(
SDValue Chain, CallingConv::ID CallConv,
7642 CCInfo.AnalyzeReturn(Outs,
7651 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7670 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7693 RetOps.push_back(Glue);
7699PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7704 EVT IntVT =
Op.getValueType();
7708 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7710 SDValue Ops[2] = {Chain, FPSIdx};
7724 bool isPPC64 = Subtarget.
isPPC64();
7725 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7745 bool isPPC64 = Subtarget.
isPPC64();
7766PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7768 bool isPPC64 = Subtarget.
isPPC64();
7802 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7803 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7814 bool isPPC64 = Subtarget.
isPPC64();
7826 Op.getOperand(0),
Op.getOperand(1));
7833 Op.getOperand(0),
Op.getOperand(1));
7837 if (
Op.getValueType().isVector())
7838 return LowerVectorLoad(
Op, DAG);
7840 assert(
Op.getValueType() == MVT::i1 &&
7841 "Custom lowering only for i1 loads");
7854 BasePtr, MVT::i8, MMO);
7862 if (
Op.getOperand(1).getValueType().isVector())
7863 return LowerVectorStore(
Op, DAG);
7865 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
7866 "Custom lowering only for i1 stores");
7885 assert(
Op.getValueType() == MVT::i1 &&
7886 "Custom lowering only for i1 results");
7914 EVT TrgVT =
Op.getValueType();
7938 if (SrcSize == 256) {
7949 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
7957 for (
unsigned i = 0; i < TrgNumElts; ++i)
7960 for (
unsigned i = 1; i <= TrgNumElts; ++i)
7964 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
7968 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
7969 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
7977 EVT ResVT =
Op.getValueType();
7978 EVT CmpVT =
Op.getOperand(0).getValueType();
7979 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
7980 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
7986 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8003 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8034 if (LHS.getValueType() == MVT::f32)
8035 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8038 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8040 DAG.
getNode(ISD::FNEG, dl, MVT::f64, LHS), Sel1, FV);
8047 if (LHS.getValueType() == MVT::f32)
8048 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8056 if (LHS.getValueType() == MVT::f32)
8057 LHS = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, LHS);
8059 DAG.
getNode(ISD::FNEG, dl, MVT::f64, LHS), TV, FV);
8070 if (
Cmp.getValueType() == MVT::f32)
8071 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8074 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8076 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8080 if (
Cmp.getValueType() == MVT::f32)
8081 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8086 if (
Cmp.getValueType() == MVT::f32)
8087 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8092 if (
Cmp.getValueType() == MVT::f32)
8093 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8098 if (
Cmp.getValueType() == MVT::f32)
8099 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8131 bool IsStrict =
Op->isStrictFPOpcode();
8140 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8142 MVT DestTy =
Op.getSimpleValueType();
8143 assert(Src.getValueType().isFloatingPoint() &&
8144 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8145 DestTy == MVT::i64) &&
8146 "Invalid FP_TO_INT types");
8147 if (Src.getValueType() == MVT::f32) {
8151 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8152 Chain = Src.getValue(1);
8154 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8156 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8157 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8166 assert((IsSigned || Subtarget.hasFPCVT()) &&
8167 "i64 FP_TO_UINT is supported only with FPCVT");
8170 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8174 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8177 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8182void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8184 const SDLoc &dl)
const {
8188 bool IsStrict =
Op->isStrictFPOpcode();
8191 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8192 (IsSigned || Subtarget.hasFPCVT());
8203 Alignment =
Align(4);
8206 SDValue Ops[] = { Chain, Tmp, FIPtr };
8208 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8210 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8214 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8223 RLI.Alignment = Alignment;
8231 const SDLoc &dl)
const {
8234 if (
Op->isStrictFPOpcode())
8241 const SDLoc &dl)
const {
8242 bool IsStrict =
Op->isStrictFPOpcode();
8245 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8246 EVT SrcVT = Src.getValueType();
8247 EVT DstVT =
Op.getValueType();
8250 if (SrcVT == MVT::f128)
8251 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8255 if (SrcVT == MVT::ppcf128) {
8256 if (DstVT == MVT::i32) {
8272 {Op.getOperand(0), Lo, Hi}, Flags);
8275 {Res.getValue(1), Res}, Flags);
8281 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8305 {Chain, Src, FltOfs}, Flags);
8309 {Chain, Val}, Flags);
8312 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8330 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8331 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8334 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8336 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8337 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8348bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8353 if (
Op->isStrictFPOpcode())
8358 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8362 Op.getOperand(0).getValueType())) {
8364 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8369 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8370 LD->isNonTemporal())
8372 if (
LD->getMemoryVT() != MemVT)
8382 RLI.Ptr =
LD->getBasePtr();
8383 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8385 "Non-pre-inc AM on PPC?");
8390 RLI.Chain =
LD->getChain();
8391 RLI.MPI =
LD->getPointerInfo();
8392 RLI.IsDereferenceable =
LD->isDereferenceable();
8393 RLI.IsInvariant =
LD->isInvariant();
8394 RLI.Alignment =
LD->getAlign();
8395 RLI.AAInfo =
LD->getAAInfo();
8396 RLI.Ranges =
LD->getRanges();
8398 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8406void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8412 SDLoc dl(NewResChain);
8415 NewResChain, DAG.
getUNDEF(MVT::Other));
8417 "A new TF really is required here");
8426bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8427 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8434 if (!Subtarget.hasP9Vector() && MMO->
getSize() <= 2)
8442 if (UI.getUse().get().getResNo() != 0)
8468 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8471 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8472 if (
Op->isStrictFPOpcode()) {
8474 Chain =
Op.getOperand(0);
8476 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8478 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8486 const SDLoc &dl)
const {
8487 assert((
Op.getValueType() == MVT::f32 ||
8488 Op.getValueType() == MVT::f64) &&
8489 "Invalid floating point type as target of conversion");
8490 assert(Subtarget.hasFPCVT() &&
8491 "Int to FP conversions with direct moves require FPCVT");
8492 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8493 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8515 for (
unsigned i = 1; i < NumConcat; ++i)
8522 const SDLoc &dl)
const {
8523 bool IsStrict =
Op->isStrictFPOpcode();
8524 unsigned Opc =
Op.getOpcode();
8525 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8528 "Unexpected conversion type");
8529 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8530 "Supports conversions to v2f64/v4f32 only.");
8537 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8542 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8545 for (
unsigned i = 0; i < WideNumElts; ++i)
8548 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8549 int SaveElts = FourEltRes ? 4 : 2;
8551 for (
int i = 0; i < SaveElts; i++)
8552 ShuffV[i * Stride] = i;
8554 for (
int i = 1; i <= SaveElts; i++)
8555 ShuffV[i * Stride - 1] = i - 1;
8563 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8564 EVT ExtVT = Src.getValueType();
8565 if (Subtarget.hasP9Altivec())
8572 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8576 {Op.getOperand(0), Extend}, Flags);
8578 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8586 bool IsStrict =
Op->isStrictFPOpcode();
8587 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8594 EVT InVT = Src.getValueType();
8595 EVT OutVT =
Op.getValueType();
8598 return LowerINT_TO_FPVector(
Op, DAG, dl);
8601 if (
Op.getValueType() == MVT::f128)
8602 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8605 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8608 if (Src.getValueType() == MVT::i1) {
8620 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8621 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8622 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8624 assert((IsSigned || Subtarget.hasFPCVT()) &&
8625 "UINT_TO_FP is supported only with FPCVT");
8627 if (Src.getValueType() == MVT::i64) {
8639 if (
Op.getValueType() == MVT::f32 &&
8640 !Subtarget.hasFPCVT() &&
8681 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8682 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8683 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8684 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8685 }
else if (Subtarget.hasLFIWAX() &&
8686 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8689 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8690 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8693 Ops, MVT::i32, MMO);
8694 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8695 }
else if (Subtarget.hasFPCVT() &&
8696 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8699 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8700 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8703 Ops, MVT::i32, MMO);
8704 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8705 }
else if (((Subtarget.hasLFIWAX() &&
8707 (Subtarget.hasFPCVT() &&
8722 "Expected an i32 store");
8728 RLI.Alignment =
Align(4);
8732 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8733 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8736 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8737 Ops, MVT::i32, MMO);
8738 Chain =
Bits.getValue(1);
8740 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
8746 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8750 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8758 assert(Src.getValueType() == MVT::i32 &&
8759 "Unhandled INT_TO_FP type in custom expander!");
8769 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8772 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8782 "Expected an i32 store");
8788 RLI.Alignment =
Align(4);
8793 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8794 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8796 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
8800 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8803 "i32->FP without LFIWAX supported only on PPC64");
8812 Chain, dl, Ext64, FIdx,
8818 MVT::f64, dl, Chain, FIdx,
8827 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8831 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8862 EVT VT =
Op.getValueType();
8868 Chain =
MFFS.getValue(1);
8873 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
8882 "Stack slot adjustment is valid only on big endian subtargets!");
8912 EVT VT =
Op.getValueType();
8916 VT ==
Op.getOperand(1).getValueType() &&
8936 SDValue OutOps[] = { OutLo, OutHi };
8941 EVT VT =
Op.getValueType();
8945 VT ==
Op.getOperand(1).getValueType() &&
8965 SDValue OutOps[] = { OutLo, OutHi };
8971 EVT VT =
Op.getValueType();
8974 VT ==
Op.getOperand(1).getValueType() &&
8994 SDValue OutOps[] = { OutLo, OutHi };
9001 EVT VT =
Op.getValueType();
9008 EVT AmtVT =
Z.getValueType();
9031 static const MVT VTys[] = {
9032 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9035 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9038 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9043 EVT CanonicalVT = VTys[SplatSize-1];
9052 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9053 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9062 EVT DestVT = MVT::Other) {
9072 EVT DestVT = MVT::Other) {
9075 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9083 LHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, LHS);
9084 RHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, RHS);
9087 for (
unsigned i = 0; i != 16; ++i)
9090 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9108 EVT VecVT = V->getValueType(0);
9109 bool RightType = VecVT == MVT::v2f64 ||
9110 (HasP8Vector && VecVT == MVT::v4f32) ||
9111 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9115 bool IsSplat =
true;
9116 bool IsLoad =
false;
9122 if (V->isConstant())
9124 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9125 if (V->getOperand(i).isUndef())
9129 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9131 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9133 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9135 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9139 if (V->getOperand(i) != Op0 ||
9140 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9143 return !(IsSplat && IsLoad);
9152 if ((
Op.getValueType() != MVT::f128) ||
9164 while (InputLoad->
getOpcode() == ISD::BITCAST)
9171 if (InputLoad->
getOpcode() != ISD::LOAD)
9181 APFloat APFloatToConvert = ArgAPFloat;
9182 bool LosesInfo =
true;
9187 ArgAPFloat = APFloatToConvert;
9209 APFloat APFloatToConvert = ArgAPFloat;
9210 bool LosesInfo =
true;
9214 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9223 EVT Ty =
Op->getValueType(0);
9226 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9235 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9239 if (Ty == MVT::v2i64) {
9242 if (MemVT == MVT::i32) {
9262 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9265 APInt APSplatBits, APSplatUndef;
9266 unsigned SplatBitSize;
9268 bool BVNIsConstantSplat =
9276 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9277 Subtarget.hasPrefixInstrs()) {
9280 if ((
Op->getValueType(0) == MVT::v2f64) &&
9315 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9322 const SDValue *InputLoad = &
Op.getOperand(0);
9327 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9328 unsigned ElementSize =
9331 assert(((ElementSize == 2 * MemorySize)
9335 "Unmatched element size and opcode!\n");
9340 unsigned NumUsesOfInputLD = 128 / ElementSize;
9342 if (BVInOp.isUndef())
9357 if (NumUsesOfInputLD == 1 &&
9360 Subtarget.hasLFIWAX()))
9369 Subtarget.isISA3_1() && ElementSize <= 16)
9372 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9374 Subtarget.hasVSX()) {
9381 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9382 LD->getMemoryVT(),
LD->getMemOperand());
9394 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9396 Subtarget.hasP8Vector()))
9403 unsigned SplatSize = SplatBitSize / 8;
9408 if (SplatBits == 0) {
9410 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9412 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9422 if (Subtarget.hasPrefixInstrs() && SplatSize == 2)
9424 Op.getValueType(), DAG, dl);
9426 if (Subtarget.hasPrefixInstrs() && SplatSize == 4)
9431 if (Subtarget.hasP9Vector() && SplatSize == 1)
9436 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9438 if (SextVal >= -16 && SextVal <= 15)
9451 if (SextVal >= -32 && SextVal <= 31) {
9456 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9457 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9460 if (VT ==
Op.getValueType())
9463 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9469 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9479 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9483 static const signed char SplatCsts[] = {
9484 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9485 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9488 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9491 int i = SplatCsts[idx];
9495 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9498 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9500 static const unsigned IIDs[] = {
9501 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9502 Intrinsic::ppc_altivec_vslw
9505 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9509 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9511 static const unsigned IIDs[] = {
9512 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9513 Intrinsic::ppc_altivec_vsrw
9516 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9520 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9521 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9523 static const unsigned IIDs[] = {
9524 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9525 Intrinsic::ppc_altivec_vrlw
9528 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9532 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9538 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9544 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9559 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9560 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9561 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9577 if (LHSID == (1*9+2)*9+3)
return LHS;
9578 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9590 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9591 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9592 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9593 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9596 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9597 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9598 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9599 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9602 for (
unsigned i = 0; i != 16; ++i)
9603 ShufIdxs[i] = (i&3)+0;
9606 for (
unsigned i = 0; i != 16; ++i)
9607 ShufIdxs[i] = (i&3)+4;
9610 for (
unsigned i = 0; i != 16; ++i)
9611 ShufIdxs[i] = (i&3)+8;
9614 for (
unsigned i = 0; i != 16; ++i)
9615 ShufIdxs[i] = (i&3)+12;
9625 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
9626 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
9628 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9636 const unsigned BytesInVector = 16;
9641 unsigned ShiftElts = 0, InsertAtByte = 0;
9645 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9646 0, 15, 14, 13, 12, 11, 10, 9};
9647 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9648 1, 2, 3, 4, 5, 6, 7, 8};
9651 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9663 bool FoundCandidate =
false;
9667 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9670 for (
unsigned i = 0; i < BytesInVector; ++i) {
9671 unsigned CurrentElement =
Mask[i];
9674 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9677 bool OtherElementsInOrder =
true;
9680 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9687 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9688 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9689 OtherElementsInOrder =
false;
9696 if (OtherElementsInOrder) {
9703 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9704 : BigEndianShifts[CurrentElement & 0xF];
9705 Swap = CurrentElement < BytesInVector;
9707 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9708 FoundCandidate =
true;
9713 if (!FoundCandidate)
9737 const unsigned NumHalfWords = 8;
9738 const unsigned BytesInVector = NumHalfWords * 2;
9747 unsigned ShiftElts = 0, InsertAtByte = 0;
9751 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9752 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9755 uint32_t OriginalOrderLow = 0x1234567;
9756 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9759 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9760 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9761 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9777 bool FoundCandidate =
false;
9780 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9781 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9783 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9791 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9792 TargetOrder = OriginalOrderLow;
9796 if (MaskOneElt == VINSERTHSrcElem &&
9797 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9798 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9799 FoundCandidate =
true;
9805 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9807 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9809 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9810 : BigEndianShifts[MaskOneElt & 0x7];
9811 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9812 Swap = MaskOneElt < NumHalfWords;
9813 FoundCandidate =
true;
9819 if (!FoundCandidate)
9836 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
9841 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
9854 auto ShuffleMask = SVN->
getMask();
9869 ShuffleMask = CommutedSV->
getMask();
9878 APInt APSplatValue, APSplatUndef;
9879 unsigned SplatBitSize;
9895 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9896 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9897 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9899 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9900 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9901 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9909 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9910 SplatVal |= (SplatVal << SplatBitSize);
9915 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
9924 assert(
Op.getValueType() == MVT::v1i128 &&
9925 "Only set v1i128 as custom, other type shouldn't reach here!");
9930 if (SHLAmt % 8 == 0) {
9931 std::array<int, 16>
Mask;
9932 std::iota(
Mask.begin(),
Mask.end(), 0);
9933 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
9937 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
9945 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
9962 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
9967 V1 =
Op.getOperand(0);
9968 V2 =
Op.getOperand(1);
9970 EVT VT =
Op.getValueType();
9973 unsigned ShiftElts, InsertAtByte;
9979 bool IsPermutedLoad =
false;
9981 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
9991 if (IsPermutedLoad) {
9992 assert((isLittleEndian || IsFourByte) &&
9993 "Unexpected size for permuted load on big endian target");
9994 SplatIdx += IsFourByte ? 2 : 1;
9995 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
9996 "Splat of a value outside of the loaded memory");
10001 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10004 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10006 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10010 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10023 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10026 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10035 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10038 if (Subtarget.hasP9Vector() &&
10050 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10054 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10057 if (Subtarget.hasPrefixInstrs()) {
10059 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10060 return SplatInsertNode;
10063 if (Subtarget.hasP9Altivec()) {
10065 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10068 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10072 if (Subtarget.hasVSX() &&
10078 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
V2.isUndef() ? V1 : V2);
10082 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10085 if (Subtarget.hasVSX() &&
10091 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64,
V2.isUndef() ? V1 : V2);
10095 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10098 if (Subtarget.hasP9Vector()) {
10102 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10106 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10110 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10114 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10118 if (Subtarget.hasVSX()) {
10125 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10132 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10139 if (
V2.isUndef()) {
10152 (Subtarget.hasP8Altivec() && (
10163 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10173 (Subtarget.hasP8Altivec() && (
10184 unsigned PFIndexes[4];
10185 bool isFourElementShuffle =
true;
10186 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10188 unsigned EltNo = 8;
10189 for (
unsigned j = 0;
j != 4; ++
j) {
10190 if (PermMask[i * 4 + j] < 0)
10193 unsigned ByteSource = PermMask[i * 4 +
j];
10194 if ((ByteSource & 3) != j) {
10195 isFourElementShuffle =
false;
10200 EltNo = ByteSource / 4;
10201 }
else if (EltNo != ByteSource / 4) {
10202 isFourElementShuffle =
false;
10206 PFIndexes[i] = EltNo;
10214 if (isFourElementShuffle) {
10216 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10217 PFIndexes[2] * 9 + PFIndexes[3];
10220 unsigned Cost = (PFEntry >> 30);
10240 if (
V2.isUndef())
V2 = V1;
10242 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10251 bool NeedSwap =
false;
10253 bool isPPC64 = Subtarget.
isPPC64();
10257 if (isLittleEndian)
10260 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10262 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10263 "XXPERM instead\n");
10271 NeedSwap = !NeedSwap;
10306 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10309 if (V1HasXXSWAPD) {
10312 else if (SrcElt < 16)
10315 if (V2HasXXSWAPD) {
10318 else if (SrcElt > 15)
10329 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10330 if (isLittleEndian)
10332 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10335 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10338 if (Opcode ==
PPCISD::XXPERM && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10339 if (V1HasXXSWAPD) {
10343 if (V2HasXXSWAPD) {
10344 dl =
SDLoc(
V2->getOperand(0));
10345 V2 =
V2->getOperand(0)->getOperand(1);
10347 if (isPPC64 && ValType != MVT::v2f64)
10349 if (isPPC64 &&
V2.getValueType() != MVT::v2f64)
10353 ShufflesHandledWithVPERM++;
10358 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10360 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10363 dbgs() <<
"With the following permute control vector:\n";
10368 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10373 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10382 unsigned IntrinsicID =
10386 switch (IntrinsicID) {
10390 case Intrinsic::ppc_altivec_vcmpbfp_p:
10394 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10398 case Intrinsic::ppc_altivec_vcmpequb_p:
10402 case Intrinsic::ppc_altivec_vcmpequh_p:
10406 case Intrinsic::ppc_altivec_vcmpequw_p:
10410 case Intrinsic::ppc_altivec_vcmpequd_p:
10411 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10417 case Intrinsic::ppc_altivec_vcmpneb_p:
10418 case Intrinsic::ppc_altivec_vcmpneh_p:
10419 case Intrinsic::ppc_altivec_vcmpnew_p:
10420 case Intrinsic::ppc_altivec_vcmpnezb_p:
10421 case Intrinsic::ppc_altivec_vcmpnezh_p:
10422 case Intrinsic::ppc_altivec_vcmpnezw_p:
10423 if (Subtarget.hasP9Altivec()) {
10424 switch (IntrinsicID) {
10427 case Intrinsic::ppc_altivec_vcmpneb_p:
10430 case Intrinsic::ppc_altivec_vcmpneh_p:
10433 case Intrinsic::ppc_altivec_vcmpnew_p:
10436 case Intrinsic::ppc_altivec_vcmpnezb_p:
10439 case Intrinsic::ppc_altivec_vcmpnezh_p:
10442 case Intrinsic::ppc_altivec_vcmpnezw_p:
10450 case Intrinsic::ppc_altivec_vcmpgefp_p:
10454 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10458 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10462 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10466 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10470 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10471 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10477 case Intrinsic::ppc_altivec_vcmpgtub_p:
10481 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10485 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10489 case Intrinsic::ppc_altivec_vcmpgtud_p:
10490 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10497 case Intrinsic::ppc_altivec_vcmpequq:
10498 case Intrinsic::ppc_altivec_vcmpgtsq:
10499 case Intrinsic::ppc_altivec_vcmpgtuq:
10500 if (!Subtarget.isISA3_1())
10502 switch (IntrinsicID) {
10505 case Intrinsic::ppc_altivec_vcmpequq:
10508 case Intrinsic::ppc_altivec_vcmpgtsq:
10511 case Intrinsic::ppc_altivec_vcmpgtuq:
10518 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10519 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10520 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10521 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10522 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10523 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10524 if (Subtarget.hasVSX()) {
10525 switch (IntrinsicID) {
10526 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10529 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10532 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10535 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10538 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10541 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10551 case Intrinsic::ppc_altivec_vcmpbfp:
10554 case Intrinsic::ppc_altivec_vcmpeqfp:
10557 case Intrinsic::ppc_altivec_vcmpequb:
10560 case Intrinsic::ppc_altivec_vcmpequh:
10563 case Intrinsic::ppc_altivec_vcmpequw:
10566 case Intrinsic::ppc_altivec_vcmpequd:
10567 if (Subtarget.hasP8Altivec())
10572 case Intrinsic::ppc_altivec_vcmpneb:
10573 case Intrinsic::ppc_altivec_vcmpneh:
10574 case Intrinsic::ppc_altivec_vcmpnew:
10575 case Intrinsic::ppc_altivec_vcmpnezb:
10576 case Intrinsic::ppc_altivec_vcmpnezh:
10577 case Intrinsic::ppc_altivec_vcmpnezw:
10578 if (Subtarget.hasP9Altivec())
10579 switch (IntrinsicID) {
10582 case Intrinsic::ppc_altivec_vcmpneb:
10585 case Intrinsic::ppc_altivec_vcmpneh:
10588 case Intrinsic::ppc_altivec_vcmpnew:
10591 case Intrinsic::ppc_altivec_vcmpnezb:
10594 case Intrinsic::ppc_altivec_vcmpnezh:
10597 case Intrinsic::ppc_altivec_vcmpnezw:
10604 case Intrinsic::ppc_altivec_vcmpgefp:
10607 case Intrinsic::ppc_altivec_vcmpgtfp:
10610 case Intrinsic::ppc_altivec_vcmpgtsb:
10613 case Intrinsic::ppc_altivec_vcmpgtsh:
10616 case Intrinsic::ppc_altivec_vcmpgtsw:
10619 case Intrinsic::ppc_altivec_vcmpgtsd:
10620 if (Subtarget.hasP8Altivec())
10625 case Intrinsic::ppc_altivec_vcmpgtub:
10628 case Intrinsic::ppc_altivec_vcmpgtuh:
10631 case Intrinsic::ppc_altivec_vcmpgtuw:
10634 case Intrinsic::ppc_altivec_vcmpgtud:
10635 if (Subtarget.hasP8Altivec())
10640 case Intrinsic::ppc_altivec_vcmpequq_p:
10641 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10642 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10643 if (!Subtarget.isISA3_1())
10645 switch (IntrinsicID) {
10648 case Intrinsic::ppc_altivec_vcmpequq_p:
10651 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10654 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10668 unsigned IntrinsicID =
10673 switch (IntrinsicID) {
10674 case Intrinsic::thread_pointer:
10680 case Intrinsic::ppc_mma_disassemble_acc: {
10681 if (Subtarget.isISAFuture()) {
10682 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10720 case Intrinsic::ppc_vsx_disassemble_pair: {
10723 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10728 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10739 case Intrinsic::ppc_mma_xxmfacc:
10740 case Intrinsic::ppc_mma_xxmtacc: {
10742 if (!Subtarget.isISAFuture())
10753 case Intrinsic::ppc_unpack_longdouble: {
10755 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
10756 "Argument of long double unpack must be 0 or 1!");
10759 Idx->getValueType(0)));
10762 case Intrinsic::ppc_compare_exp_lt:
10763 case Intrinsic::ppc_compare_exp_gt:
10764 case Intrinsic::ppc_compare_exp_eq:
10765 case Intrinsic::ppc_compare_exp_uo: {
10767 switch (IntrinsicID) {
10768 case Intrinsic::ppc_compare_exp_lt:
10771 case Intrinsic::ppc_compare_exp_gt:
10774 case Intrinsic::ppc_compare_exp_eq:
10777 case Intrinsic::ppc_compare_exp_uo:
10783 PPC::SELECT_CC_I4, dl, MVT::i32,
10784 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10785 Op.getOperand(1), Op.getOperand(2)),
10787 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10788 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10791 case Intrinsic::ppc_test_data_class: {
10792 EVT OpVT =
Op.getOperand(1).getValueType();
10793 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
10794 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
10798 PPC::SELECT_CC_I4, dl, MVT::i32,
10799 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10802 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10803 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10806 case Intrinsic::ppc_fnmsub: {
10807 EVT VT =
Op.getOperand(1).getValueType();
10808 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
10812 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
10814 Op.getOperand(2),
Op.getOperand(3));
10816 case Intrinsic::ppc_convert_f128_to_ppcf128:
10817 case Intrinsic::ppc_convert_ppcf128_to_f128: {
10818 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10819 ? RTLIB::CONVERT_PPCF128_F128
10820 : RTLIB::CONVERT_F128_PPCF128;
10821 MakeLibCallOptions CallOptions;
10822 std::pair<SDValue, SDValue>
Result =
10823 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
10827 case Intrinsic::ppc_maxfe:
10828 case Intrinsic::ppc_maxfl:
10829 case Intrinsic::ppc_maxfs:
10830 case Intrinsic::ppc_minfe:
10831 case Intrinsic::ppc_minfl:
10832 case Intrinsic::ppc_minfs: {
10833 EVT VT =
Op.getValueType();
10836 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
10837 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
10840 if (IntrinsicID == Intrinsic::ppc_minfe ||
10841 IntrinsicID == Intrinsic::ppc_minfl ||
10842 IntrinsicID == Intrinsic::ppc_minfs)
10864 Op.getOperand(1),
Op.getOperand(2),
10866 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
10875 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
10890 BitNo = 0; InvertBit =
false;
10893 BitNo = 0; InvertBit =
true;
10896 BitNo = 2; InvertBit =
false;
10899 BitNo = 2; InvertBit =
true;
10924 case Intrinsic::ppc_cfence: {
10925 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
10926 assert(Subtarget.
isPPC64() &&
"Only 64-bit is supported for now.");
10927 SDValue Val =
Op.getOperand(ArgStart + 1);
10929 if (Ty == MVT::i128) {
10957 int VectorIndex = 0;
10969 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
10970 "Expecting an atomic compare-and-swap here.");
10973 EVT MemVT = AtomicNode->getMemoryVT();
10991 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
10992 Ops.
push_back(AtomicNode->getOperand(i));
11004 EVT MemVT =
N->getMemoryVT();
11006 "Expect quadword atomic operations");
11008 unsigned Opc =
N->getOpcode();
11010 case ISD::ATOMIC_LOAD: {
11016 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11017 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11020 Ops, MemVT,
N->getMemOperand());
11027 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11031 case ISD::ATOMIC_STORE: {
11037 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11047 N->getMemOperand());
11059 enum DataClassMask {
11061 DC_NEG_INF = 1 << 4,
11062 DC_POS_INF = 1 << 5,
11063 DC_NEG_ZERO = 1 << 2,
11064 DC_POS_ZERO = 1 << 3,
11065 DC_NEG_SUBNORM = 1,
11066 DC_POS_SUBNORM = 1 << 1,
11069 EVT VT =
Op.getValueType();
11071 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11072 : VT == MVT::f64 ? PPC::XSTSTDCDP
11083 return DAG.
getNOT(Dl, Rev, MVT::i1);
11090 TestOp, Dl, MVT::i32,
11092 DC_NEG_ZERO | DC_POS_ZERO |
11093 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11099 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11105 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11110 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11123 bool IsQuiet = Mask &
fcQNan;
11129 if (VT == MVT::f128) {
11133 QuietMask = 0x8000;
11134 }
else if (VT == MVT::f64) {
11146 QuietMask = 0x80000;
11147 }
else if (VT == MVT::f32) {
11149 QuietMask = 0x400000;
11165 unsigned NativeMask = 0;
11167 NativeMask |= DC_NAN;
11169 NativeMask |= DC_NEG_INF;
11171 NativeMask |= DC_POS_INF;
11173 NativeMask |= DC_NEG_ZERO;
11175 NativeMask |= DC_POS_ZERO;
11177 NativeMask |= DC_NEG_SUBNORM;
11179 NativeMask |= DC_POS_SUBNORM;
11182 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11184 TestOp, Dl, MVT::i32,
11193 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11220 "Should only be called for ISD::INSERT_VECTOR_ELT");
11224 EVT VT =
Op.getValueType();
11229 if (VT == MVT::v2f64 &&
C)
11232 if (Subtarget.hasP9Vector()) {
11241 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11247 BitcastLoad,
Op.getOperand(2));
11248 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11252 if (Subtarget.isISA3_1()) {
11253 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11257 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11258 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11268 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11271 unsigned InsertAtElement =
C->getZExtValue();
11272 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11274 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11288 EVT VT =
Op.getValueType();
11290 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11296 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11297 "Type unsupported without MMA");
11298 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11299 "Type unsupported without paired vector support");
11304 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11306 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11316 std::reverse(Loads.
begin(), Loads.
end());
11317 std::reverse(LoadChains.
begin(), LoadChains.
end());
11335 EVT StoreVT =
Value.getValueType();
11337 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11343 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11344 "Type unsupported without MMA");
11345 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11346 "Type unsupported without paired vector support");
11349 unsigned NumVecs = 2;
11350 if (StoreVT == MVT::v512i1) {
11351 if (Subtarget.isISAFuture()) {
11352 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11354 PPC::DMXXEXTFDMR512, dl,
ArrayRef(ReturnTypes, 2),
Op.getOperand(1));
11357 Value2 =
SDValue(ExtNode, 1);
11362 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11363 unsigned VecNum = Subtarget.
isLittleEndian() ? NumVecs - 1 - Idx : Idx;
11365 if (Subtarget.isISAFuture()) {
11366 VecNum = Subtarget.
isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
11368 Idx > 1 ? Value2 :
Value,
11375 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11389 if (
Op.getValueType() == MVT::v4i32) {
11390 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11399 LHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, LHS);
11400 RHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHS);
11401 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
11406 LHS, RHS, DAG, dl, MVT::v4i32);
11409 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11414 }
else if (
Op.getValueType() == MVT::v16i8) {
11415 SDValue LHS =
Op.getOperand(0), RHS =
Op.getOperand(1);
11420 LHS, RHS, DAG, dl, MVT::v8i16);
11421 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
11425 LHS, RHS, DAG, dl, MVT::v8i16);
11426 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
11433 for (
unsigned i = 0; i != 8; ++i) {
11434 if (isLittleEndian) {
11436 Ops[i*2+1] = 2*i+16;
11439 Ops[i*2+1] = 2*i+1+16;
11442 if (isLittleEndian)
11452 bool IsStrict =
Op->isStrictFPOpcode();
11453 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11454 !Subtarget.hasP9Vector())
11463 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
11464 "Should only be called for ISD::FP_EXTEND");
11468 if (
Op.getValueType() != MVT::v2f64 ||
11469 Op.getOperand(0).getValueType() != MVT::v2f32)
11481 "Node should have 2 operands with second one being a constant!");
11493 int DWord = Idx >> 1;
11516 LD->getMemoryVT(),
LD->getMemOperand());
11529 LD->getMemoryVT(),
LD->getMemOperand());
11540 switch (
Op.getOpcode()) {
11542 case ISD::FPOW:
return lowerPow(
Op, DAG);
11543 case ISD::FSIN:
return lowerSin(
Op, DAG);
11544 case ISD::FCOS:
return lowerCos(
Op, DAG);
11545 case ISD::FLOG:
return lowerLog(
Op, DAG);
11546 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
11547 case ISD::FEXP:
return lowerExp(
Op, DAG);
11556 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
11557 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
11559 case ISD::INLINEASM:
11560 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
11562 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
11563 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
11564 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
11566 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
11567 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
11568 case ISD::GET_DYNAMIC_AREA_OFFSET:
11569 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11576 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
11577 case ISD::STORE:
return LowerSTORE(
Op, DAG);
11595 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11596 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11605 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
11608 return LowerFP_ROUND(
Op, DAG);
11614 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
11621 return LowerINTRINSIC_VOID(
Op, DAG);
11623 return LowerBSWAP(
Op, DAG);
11624 case ISD::ATOMIC_CMP_SWAP:
11625 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11626 case ISD::ATOMIC_STORE:
11627 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11629 return LowerIS_FPCLASS(
Op, DAG);
11637 switch (
N->getOpcode()) {
11639 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11640 case ISD::ATOMIC_LOAD: {
11646 case ISD::READCYCLECOUNTER: {
11657 Intrinsic::loop_decrement)
11660 assert(
N->getValueType(0) == MVT::i1 &&
11661 "Unexpected result type for CTR decrement intrinsic");
11663 N->getValueType(0));
11674 case Intrinsic::ppc_pack_longdouble:
11676 N->getOperand(2),
N->getOperand(1)));
11678 case Intrinsic::ppc_maxfe:
11679 case Intrinsic::ppc_minfe:
11680 case Intrinsic::ppc_fnmsub:
11681 case Intrinsic::ppc_convert_f128_to_ppcf128:
11691 EVT VT =
N->getValueType(0);
11693 if (VT == MVT::i64) {
11706 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11710 Results.push_back(LoweredValue);
11711 if (
N->isStrictFPOpcode())
11716 if (!
N->getValueType(0).isVector())
11730 case ISD::FP_EXTEND:
11743 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
11745 return Builder.CreateCall(Func, {});
11768 return Builder.CreateCall(
11770 Builder.GetInsertBlock()->getParent()->getParent(),
11771 Intrinsic::ppc_cfence, {Inst->getType()}),
11781 unsigned AtomicSize,
11782 unsigned BinOpcode,
11783 unsigned CmpOpcode,
11784 unsigned CmpPred)
const {
11788 auto LoadMnemonic = PPC::LDARX;
11789 auto StoreMnemonic = PPC::STDCX;
11790 switch (AtomicSize) {
11794 LoadMnemonic = PPC::LBARX;
11795 StoreMnemonic = PPC::STBCX;
11796 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11799 LoadMnemonic = PPC::LHARX;
11800 StoreMnemonic = PPC::STHCX;
11801 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11804 LoadMnemonic = PPC::LWARX;
11805 StoreMnemonic = PPC::STWCX;
11808 LoadMnemonic = PPC::LDARX;
11809 StoreMnemonic = PPC::STDCX;
11825 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11829 F->insert(It, loop2MBB);
11830 F->insert(It, exitMBB);
11836 Register TmpReg = (!BinOpcode) ? incr :
11837 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
11838 : &PPC::GPRCRegClass);
11863 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
11868 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
11870 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
11871 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
11872 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
11900 switch(
MI.getOpcode()) {
11904 return TII->isSignExtended(
MI.getOperand(1).getReg(),
11905 &
MI.getMF()->getRegInfo());
11929 case PPC::EXTSB8_32_64:
11930 case PPC::EXTSB8_rec:
11931 case PPC::EXTSB_rec:
11934 case PPC::EXTSH8_32_64:
11935 case PPC::EXTSH8_rec:
11936 case PPC::EXTSH_rec:
11938 case PPC::EXTSWSLI:
11939 case PPC::EXTSWSLI_32_64:
11940 case PPC::EXTSWSLI_32_64_rec:
11941 case PPC::EXTSWSLI_rec:
11942 case PPC::EXTSW_32:
11943 case PPC::EXTSW_32_64:
11944 case PPC::EXTSW_32_64_rec:
11945 case PPC::EXTSW_rec:
11948 case PPC::SRAWI_rec:
11949 case PPC::SRAW_rec:
11958 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
11968 bool IsSignExtended =
11971 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
11972 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
11973 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
11974 .
addReg(
MI.getOperand(3).getReg());
11975 MI.getOperand(3).setReg(ValueReg);
11979 if (Subtarget.hasPartwordAtomics())
11987 bool is64bit = Subtarget.
isPPC64();
11989 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12000 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12004 F->insert(It, loop2MBB);
12005 F->insert(It, exitMBB);
12011 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12014 Register PtrReg = RegInfo.createVirtualRegister(RC);
12015 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
12017 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
12018 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
12019 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
12020 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
12021 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
12022 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
12023 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
12024 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
12025 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
12026 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
12029 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
12056 if (ptrA != ZeroReg) {
12057 Ptr1Reg = RegInfo.createVirtualRegister(RC);
12058 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12066 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12067 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12070 .
addImm(is8bit ? 28 : 27);
12071 if (!isLittleEndian)
12072 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12074 .
addImm(is8bit ? 24 : 16);
12076 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12081 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12091 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12095 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12100 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12104 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12107 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12114 Register SReg = RegInfo.createVirtualRegister(GPRC);
12115 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12119 unsigned ValueReg = SReg;
12120 unsigned CmpReg = Incr2Reg;
12121 if (CmpOpcode == PPC::CMPW) {
12122 ValueReg = RegInfo.createVirtualRegister(GPRC);
12123 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12126 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
12127 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12129 ValueReg = ValueSReg;
12161 .
addImm(is8bit ? 24 : 16)
12182 Register DstReg =
MI.getOperand(0).getReg();
12184 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12185 Register mainDstReg =
MRI.createVirtualRegister(RC);
12186 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12189 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12190 "Invalid Pointer Size!");
12238 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12239 Register BufReg =
MI.getOperand(1).getReg();
12254 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12256 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12259 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12282 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12303 TII->get(PPC::PHI), DstReg)
12307 MI.eraseFromParent();
12321 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12322 "Invalid Pointer Size!");
12325 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12328 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12329 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12343 Register BufReg =
MI.getOperand(0).getReg();
12348 if (PVT == MVT::i64) {
12360 if (PVT == MVT::i64) {
12372 if (PVT == MVT::i64) {
12384 if (PVT == MVT::i64) {
12396 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12406 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12409 MI.eraseFromParent();
12425 "Unexpected stack alignment");
12429 unsigned StackProbeSize =
12432 StackProbeSize &= ~(StackAlign - 1);
12433 return StackProbeSize ? StackProbeSize : StackAlign;
12445 const bool isPPC64 = Subtarget.
isPPC64();
12477 MF->
insert(MBBIter, TestMBB);
12478 MF->
insert(MBBIter, BlockMBB);
12479 MF->
insert(MBBIter, TailMBB);
12484 Register DstReg =
MI.getOperand(0).getReg();
12485 Register NegSizeReg =
MI.getOperand(1).getReg();
12486 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12487 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12488 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12489 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12495 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12497 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12503 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12504 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12506 .
addDef(ActualNegSizeReg)
12508 .
add(
MI.getOperand(2))
12509 .
add(
MI.getOperand(3));
12515 .
addReg(ActualNegSizeReg);
12518 int64_t NegProbeSize = -(int64_t)ProbeSize;
12520 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12522 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12524 .
addImm(NegProbeSize >> 16);
12528 .
addImm(NegProbeSize & 0xFFFF);
12535 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12537 .
addReg(ActualNegSizeReg)
12539 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12543 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12546 .
addReg(ActualNegSizeReg);
12555 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12556 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12570 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12581 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12583 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12584 MaxCallFrameSizeReg)
12585 .
add(
MI.getOperand(2))
12586 .
add(
MI.getOperand(3));
12587 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12589 .
addReg(MaxCallFrameSizeReg);
12598 MI.eraseFromParent();
12600 ++NumDynamicAllocaProbed;
12607 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12608 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12610 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12623 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12624 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12626 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12627 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12641 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12642 MI.getOpcode() == PPC::SELECT_CC_I8 ||
MI.getOpcode() == PPC::SELECT_I4 ||
12643 MI.getOpcode() == PPC::SELECT_I8) {
12645 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12646 MI.getOpcode() == PPC::SELECT_CC_I8)
12650 Cond.push_back(
MI.getOperand(1));
12653 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12654 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12655 }
else if (
MI.getOpcode() == PPC::SELECT_CC_F4 ||
12656 MI.getOpcode() == PPC::SELECT_CC_F8 ||
12657 MI.getOpcode() == PPC::SELECT_CC_F16 ||
12658 MI.getOpcode() == PPC::SELECT_CC_VRRC ||
12659 MI.getOpcode() == PPC::SELECT_CC_VSFRC ||
12660 MI.getOpcode() == PPC::SELECT_CC_VSSRC ||
12661 MI.getOpcode() == PPC::SELECT_CC_VSRC ||
12662 MI.getOpcode() == PPC::SELECT_CC_SPE4 ||
12663 MI.getOpcode() == PPC::SELECT_CC_SPE ||
12664 MI.getOpcode() == PPC::SELECT_F4 ||
12665 MI.getOpcode() == PPC::SELECT_F8 ||
12666 MI.getOpcode() == PPC::SELECT_F16 ||
12667 MI.getOpcode() == PPC::SELECT_SPE ||
12668 MI.getOpcode() == PPC::SELECT_SPE4 ||
12669 MI.getOpcode() == PPC::SELECT_VRRC ||
12670 MI.getOpcode() == PPC::SELECT_VSFRC ||
12671 MI.getOpcode() == PPC::SELECT_VSSRC ||
12672 MI.getOpcode() == PPC::SELECT_VSRC) {
12687 F->insert(It, copy0MBB);
12688 F->insert(It, sinkMBB);
12699 if (
MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8 ||
12700 MI.getOpcode() == PPC::SELECT_F4 ||
MI.getOpcode() == PPC::SELECT_F8 ||
12701 MI.getOpcode() == PPC::SELECT_F16 ||
12702 MI.getOpcode() == PPC::SELECT_SPE4 ||
12703 MI.getOpcode() == PPC::SELECT_SPE ||
12704 MI.getOpcode() == PPC::SELECT_VRRC ||
12705 MI.getOpcode() == PPC::SELECT_VSFRC ||
12706 MI.getOpcode() == PPC::SELECT_VSSRC ||
12707 MI.getOpcode() == PPC::SELECT_VSRC) {
12709 .
addReg(
MI.getOperand(1).getReg())
12712 unsigned SelectPred =
MI.getOperand(4).getImm();
12715 .
addReg(
MI.getOperand(1).getReg())
12732 .
addReg(
MI.getOperand(3).getReg())
12734 .
addReg(
MI.getOperand(2).getReg())
12736 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12752 F->insert(It, readMBB);
12753 F->insert(It, sinkMBB);
12764 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
12772 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12774 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
12784 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12786 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12788 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12790 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
12793 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
12795 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
12797 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
12799 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
12802 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
12804 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
12806 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
12808 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
12811 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
12813 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
12815 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
12817 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
12820 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
12822 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
12824 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
12826 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
12829 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
12831 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
12833 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
12835 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
12838 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
12840 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
12842 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
12844 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
12847 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
12849 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
12851 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
12853 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
12856 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
12858 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
12860 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
12862 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
12865 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
12867 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
12869 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
12871 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
12874 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
12876 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
12878 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
12880 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
12882 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
12883 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
12884 (Subtarget.hasPartwordAtomics() &&
12885 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
12886 (Subtarget.hasPartwordAtomics() &&
12887 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
12888 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
12890 auto LoadMnemonic = PPC::LDARX;
12891 auto StoreMnemonic = PPC::STDCX;
12892 switch (
MI.getOpcode()) {
12895 case PPC::ATOMIC_CMP_SWAP_I8:
12896 LoadMnemonic = PPC::LBARX;
12897 StoreMnemonic = PPC::STBCX;
12898 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12900 case PPC::ATOMIC_CMP_SWAP_I16:
12901 LoadMnemonic = PPC::LHARX;
12902 StoreMnemonic = PPC::STHCX;
12903 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12905 case PPC::ATOMIC_CMP_SWAP_I32:
12906 LoadMnemonic = PPC::LWARX;
12907 StoreMnemonic = PPC::STWCX;
12909 case PPC::ATOMIC_CMP_SWAP_I64:
12910 LoadMnemonic = PPC::LDARX;
12911 StoreMnemonic = PPC::STDCX;
12918 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
12919 Register oldval =
MI.getOperand(3).getReg();
12920 Register newval =
MI.getOperand(4).getReg();
12927 F->insert(It, loop2MBB);
12928 F->insert(It, exitMBB);
12949 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
12975 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
12976 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
12980 bool is64bit = Subtarget.
isPPC64();
12982 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
12987 Register oldval =
MI.getOperand(3).getReg();
12988 Register newval =
MI.getOperand(4).getReg();
12995 F->insert(It, loop2MBB);
12996 F->insert(It, exitMBB);
13003 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13006 Register PtrReg = RegInfo.createVirtualRegister(RC);
13007 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13009 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13010 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
13011 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
13012 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
13013 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
13014 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13015 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13016 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13017 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13018 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13019 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13021 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
13022 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13023 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13054 if (ptrA != ZeroReg) {
13055 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13056 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13065 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13066 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13069 .
addImm(is8bit ? 28 : 27);
13070 if (!isLittleEndian)
13071 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13073 .
addImm(is8bit ? 24 : 16);
13075 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13080 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13085 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13088 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13095 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13099 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13102 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13105 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13110 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13127 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13151 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13161 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
13176 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13184 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13185 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13186 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13187 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13188 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13189 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13192 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13193 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13196 Register Dest = RegInfo.createVirtualRegister(
13197 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13201 .
addReg(
MI.getOperand(1).getReg())
13204 MI.getOperand(0).getReg())
13205 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13206 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13209 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13212 MI.getOperand(0).getReg())
13214 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13216 unsigned Imm =
MI.getOperand(1).getImm();
13219 MI.getOperand(0).getReg())
13221 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13223 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13226 if (
MRI.use_empty(OldFPSCRReg))
13227 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13229 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13240 unsigned Mode =
MI.getOperand(1).getImm();
13241 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13245 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13248 }
else if (
MI.getOpcode() == PPC::SETRND) {
13256 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13257 if (Subtarget.hasDirectMove()) {
13258 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13262 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13265 if (RC == &PPC::F8RCRegClass) {
13267 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
13268 "Unsupported RegClass.");
13270 StoreOp = PPC::STFD;
13274 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
13275 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13276 "Unsupported RegClass.");
13309 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13312 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13324 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13326 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13328 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13329 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13334 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13335 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13340 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
13341 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13347 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
13348 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13357 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13361 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13362 if (
MRI.use_empty(OldFPSCRReg))
13363 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13365 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13368 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13374 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13375 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13377 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13384 .
addUse(Src, 0, PPC::sub_gp8_x1);
13387 .
addUse(Src, 0, PPC::sub_gp8_x0);
13388 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13389 MI.getOpcode() == PPC::STQX_PSEUDO) {
13395 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13401 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13402 :
TII->get(PPC::STQ))
13410 MI.eraseFromParent();
13423 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13426 return RefinementSteps;
13432 EVT VT =
Op.getValueType();
13435 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13459PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13462 EVT VT =
Op.getValueType();
13463 if (VT != MVT::f64 &&
13464 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13471 int Enabled,
int &RefinementSteps,
13472 bool &UseOneConstNR,
13473 bool Reciprocal)
const {
13475 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13476 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13477 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13478 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13484 UseOneConstNR = !Subtarget.needsTwoConstNR();
13492 int &RefinementSteps)
const {
13494 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13495 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13496 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13497 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13505unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13533 Base = Loc.getOperand(0);
13543 unsigned Bytes,
int Dist,
13557 if (FS != BFS || FS != (
int)Bytes)
return false;
13561 SDValue Base1 = Loc, Base2 = BaseLoc;
13562 int64_t Offset1 = 0, Offset2 = 0;
13565 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13575 if (isGA1 && isGA2 && GV1 == GV2)
13576 return Offset1 == (Offset2 + Dist*Bytes);
13583 unsigned Bytes,
int Dist,
13586 EVT VT = LS->getMemoryVT();
13587 SDValue Loc = LS->getBasePtr();
13594 default:
return false;
13595 case Intrinsic::ppc_altivec_lvx:
13596 case Intrinsic::ppc_altivec_lvxl:
13597 case Intrinsic::ppc_vsx_lxvw4x:
13598 case Intrinsic::ppc_vsx_lxvw4x_be:
13601 case Intrinsic::ppc_vsx_lxvd2x:
13602 case Intrinsic::ppc_vsx_lxvd2x_be:
13605 case Intrinsic::ppc_altivec_lvebx:
13608 case Intrinsic::ppc_altivec_lvehx:
13611 case Intrinsic::ppc_altivec_lvewx:
13622 default:
return false;
13623 case Intrinsic::ppc_altivec_stvx:
13624 case Intrinsic::ppc_altivec_stvxl:
13625 case Intrinsic::ppc_vsx_stxvw4x:
13628 case Intrinsic::ppc_vsx_stxvd2x:
13631 case Intrinsic::ppc_vsx_stxvw4x_be:
13634 case Intrinsic::ppc_vsx_stxvd2x_be:
13637 case Intrinsic::ppc_altivec_stvebx:
13640 case Intrinsic::ppc_altivec_stvehx:
13643 case Intrinsic::ppc_altivec_stvewx:
13660 SDValue Chain = LD->getChain();
13661 EVT VT = LD->getMemoryVT();
13670 while (!Queue.empty()) {
13671 SDNode *ChainNext = Queue.pop_back_val();
13672 if (!Visited.
insert(ChainNext).second)
13679 if (!Visited.
count(ChainLD->getChain().getNode()))
13680 Queue.push_back(ChainLD->getChain().getNode());
13682 for (
const SDUse &O : ChainNext->
ops())
13683 if (!Visited.
count(O.getNode()))
13684 Queue.push_back(O.getNode());
13686 LoadRoots.
insert(ChainNext);
13697 for (
SDNode *
I : LoadRoots) {
13698 Queue.push_back(
I);
13700 while (!Queue.empty()) {
13701 SDNode *LoadRoot = Queue.pop_back_val();
13702 if (!Visited.
insert(LoadRoot).second)
13714 Queue.push_back(U);
13747 auto Final = Shifted;
13758 DAGCombinerInfo &DCI)
const {
13766 if (!DCI.isAfterLegalizeDAG())
13776 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13780 if (OpSize <
Size) {
13798 DAGCombinerInfo &DCI)
const {
13802 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
13813 N->getValueType(0) != MVT::i1)
13816 if (
N->getOperand(0).getValueType() != MVT::i32 &&
13817 N->getOperand(0).getValueType() != MVT::i64)
13827 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
13838 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
13861 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
13862 N->getOperand(0).getOpcode() !=
ISD::OR &&
13863 N->getOperand(0).getOpcode() !=
ISD::XOR &&
13873 N->getOperand(1).getOpcode() !=
ISD::AND &&
13874 N->getOperand(1).getOpcode() !=
ISD::OR &&
13875 N->getOperand(1).getOpcode() !=
ISD::XOR &&
13888 for (
unsigned i = 0; i < 2; ++i) {
13892 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
13904 while (!BinOps.
empty()) {
13912 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
13946 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
13950 for (
const SDNode *
User : Inputs[i].getNode()->uses()) {
13970 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
13971 for (
const SDNode *
User : PromOps[i].getNode()->uses()) {
13992 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14001 std::list<HandleSDNode> PromOpHandles;
14002 for (
auto &PromOp : PromOps)
14003 PromOpHandles.emplace_back(PromOp);
14010 while (!PromOpHandles.empty()) {
14012 PromOpHandles.pop_back();
14021 PromOpHandles.emplace_front(PromOp);
14035 default:
C = 0;
break;
14048 PromOpHandles.emplace_front(PromOp);
14056 for (
unsigned i = 0; i < 2; ++i)
14066 return N->getOperand(0);
14074 DAGCombinerInfo &DCI)
const {
14092 if (
N->getValueType(0) != MVT::i32 &&
14093 N->getValueType(0) != MVT::i64)
14096 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14097 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14100 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14101 N->getOperand(0).getOpcode() !=
ISD::OR &&
14102 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14113 while (!BinOps.
empty()) {
14121 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14152 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14156 for (
SDNode *
User : Inputs[i].getNode()->uses()) {
14164 SelectTruncOp[0].
insert(std::make_pair(
User,
14168 SelectTruncOp[0].
insert(std::make_pair(
User,
14171 SelectTruncOp[1].
insert(std::make_pair(
User,
14177 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14178 for (
SDNode *
User : PromOps[i].getNode()->uses()) {
14186 SelectTruncOp[0].
insert(std::make_pair(
User,
14190 SelectTruncOp[0].
insert(std::make_pair(
User,
14193 SelectTruncOp[1].
insert(std::make_pair(
User,
14199 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14200 bool ReallyNeedsExt =
false;
14204 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14209 Inputs[i].getOperand(0).getValueSizeInBits();
14210 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14215 OpBits-PromBits))) ||
14218 (OpBits-(PromBits-1)))) {
14219 ReallyNeedsExt =
true;
14227 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14234 SDValue InSrc = Inputs[i].getOperand(0);
14248 std::list<HandleSDNode> PromOpHandles;
14249 for (
auto &PromOp : PromOps)
14250 PromOpHandles.emplace_back(PromOp);
14256 while (!PromOpHandles.empty()) {
14258 PromOpHandles.pop_back();
14262 default:
C = 0;
break;
14275 PromOpHandles.emplace_front(PromOp);
14285 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14287 PromOpHandles.emplace_front(PromOp);
14296 for (
unsigned i = 0; i < 2; ++i) {
14314 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14315 if (SI0 != SelectTruncOp[0].end())
14317 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14318 if (SI1 != SelectTruncOp[1].end())
14327 if (!ReallyNeedsExt)
14328 return N->getOperand(0);
14335 N->getValueSizeInBits(0), PromBits),
14336 dl,
N->getValueType(0)));
14339 "Invalid extension type");
14342 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14350 DAGCombinerInfo &DCI)
const {
14352 "Should be called with a SETCC node");
14370 EVT VT =
N->getValueType(0);
14371 EVT OpVT = LHS.getValueType();
14377 return DAGCombineTruncBoolExt(
N, DCI);
14384 Op.getValueType() == MVT::f64;
14396combineElementTruncationToVectorTruncation(
SDNode *
N,
14397 DAGCombinerInfo &DCI)
const {
14399 "Should be called with a BUILD_VECTOR node");
14406 "The input operand must be an fp-to-int conversion.");
14415 bool IsSplat =
true;
14420 EVT TargetVT =
N->getValueType(0);
14421 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14426 if (NextConversion != FirstConversion)
14434 if (
N->getOperand(i) != FirstInput)
14445 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14446 SDValue In =
N->getOperand(i).getOperand(0);
14469 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14471 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14484 "Should be called with a BUILD_VECTOR node");
14489 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14492 bool InputsAreConsecutiveLoads =
true;
14493 bool InputsAreReverseConsecutive =
true;
14494 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14496 bool IsRoundOfExtLoad =
false;
14505 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
14506 N->getNumOperands() == 1)
14509 if (!IsRoundOfExtLoad)
14514 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14516 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14519 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14521 if (NextInput.
getOpcode() != ISD::LOAD)
14525 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14536 InputsAreConsecutiveLoads =
false;
14538 InputsAreReverseConsecutive =
false;
14541 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14546 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14547 "The loads cannot be both consecutive and reverse consecutive.");
14551 if (InputsAreConsecutiveLoads) {
14552 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14556 ReturnSDVal = WideLoad;
14557 }
else if (InputsAreReverseConsecutive) {
14559 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14564 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14568 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14572 for (
auto *LD : InputLoads)
14574 return ReturnSDVal;
14585 unsigned NumElems = Input.getValueType().getVectorNumElements();
14591 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14593 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14595 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14596 CorrectElems = CorrectElems >> 8;
14597 Elems = Elems >> 8;
14602 DAG.
getUNDEF(Input.getValueType()), ShuffleMask);
14604 EVT VT =
N->getValueType(0);
14608 Input.getValueType().getVectorElementType(),
14642 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14662 if (Input && Input != Extract.
getOperand(0))
14668 Elems = Elems << 8;
14677 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14678 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14685 int TgtElemArrayIdx;
14687 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14688 if (InputSize + OutputSize == 40)
14689 TgtElemArrayIdx = 0;
14690 else if (InputSize + OutputSize == 72)
14691 TgtElemArrayIdx = 1;
14692 else if (InputSize + OutputSize == 48)
14693 TgtElemArrayIdx = 2;
14694 else if (InputSize + OutputSize == 80)
14695 TgtElemArrayIdx = 3;
14696 else if (InputSize + OutputSize == 96)
14697 TgtElemArrayIdx = 4;
14701 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14703 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14704 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14705 if (Elems != CorrectElems) {
14721 if (
N->getValueType(0) != MVT::v1i128)
14731 EVT MemoryType = LD->getMemoryVT();
14735 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
14736 MemoryType == MVT::i32 || MemoryType == MVT::i64;
14739 if (!ValidLDType ||
14745 LD->getChain(), LD->getBasePtr(),
14749 DAG.
getVTList(MVT::v1i128, MVT::Other),
14750 LoadOps, MemoryType, LD->getMemOperand());
14754 DAGCombinerInfo &DCI)
const {
14756 "Should be called with a BUILD_VECTOR node");
14761 if (!Subtarget.hasVSX())
14769 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14784 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
14793 if (Subtarget.isISA3_1()) {
14799 if (
N->getValueType(0) != MVT::v2f64)
14810 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
14821 if (!Ext1Op || !Ext2Op)
14830 if (FirstElem == 0 && SecondElem == 1)
14832 else if (FirstElem == 2 && SecondElem == 3)
14840 return DAG.
getNode(NodeType, dl, MVT::v2f64,
14845 DAGCombinerInfo &DCI)
const {
14848 "Need an int -> FP conversion node here");
14859 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
14861 if (!
Op.getOperand(0).getValueType().isSimple())
14863 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
14864 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
14867 SDValue FirstOperand(
Op.getOperand(0));
14868 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
14869 (FirstOperand.getValueType() == MVT::i8 ||
14870 FirstOperand.getValueType() == MVT::i16);
14871 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
14873 bool DstDouble =
Op.getValueType() == MVT::f64;
14874 unsigned ConvOp =
Signed ?
14881 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
14884 Ops, MVT::i8, LDN->getMemOperand());
14888 SDValue ExtOps[] = { Ld, WidthConst };
14890 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
14892 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
14900 if (
Op.getOperand(0).getValueType() == MVT::i32)
14904 "UINT_TO_FP is supported only with FPCVT");
14908 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
14913 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
14920 Subtarget.hasFPCVT()) ||
14922 SDValue Src =
Op.getOperand(0).getOperand(0);
14923 if (Src.getValueType() == MVT::f32) {
14924 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
14925 DCI.AddToWorklist(Src.getNode());
14926 }
else if (Src.getValueType() != MVT::f64) {
14938 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
14941 DCI.AddToWorklist(
FP.getNode());
14965 switch (
N->getOpcode()) {
14970 Chain = LD->getChain();
14971 Base = LD->getBasePtr();
14972 MMO = LD->getMemOperand();
14991 MVT VecTy =
N->getValueType(0).getSimpleVT();
14999 Chain = Load.getValue(1);
15005 if (VecTy != MVT::v2f64) {
15032 switch (
N->getOpcode()) {
15037 Chain = ST->getChain();
15038 Base = ST->getBasePtr();
15039 MMO = ST->getMemOperand();
15059 SDValue Src =
N->getOperand(SrcOpnd);
15060 MVT VecTy = Src.getValueType().getSimpleVT();
15063 if (VecTy != MVT::v2f64) {
15064 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
15069 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15075 StoreOps, VecTy, MMO);
15082 DAGCombinerInfo &DCI)
const {
15085 unsigned Opcode =
N->getOperand(1).getOpcode();
15087 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15091 &&
"Not a FP_TO_INT Instruction!");
15094 EVT Op1VT =
N->getOperand(1).getValueType();
15097 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15101 bool ValidTypeForStoreFltAsInt =
15102 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15103 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15106 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15109 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15132 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15133 for (
int i = 1, e = Mask.size(); i < e; i++) {
15134 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15136 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15138 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15150 FirstOp =
Op.getOperand(i);
15157 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15165 if (
Op.getOpcode() != ISD::BITCAST)
15167 Op =
Op.getOperand(0);
15182 int LHSMaxIdx,
int RHSMinIdx,
15183 int RHSMaxIdx,
int HalfVec,
15184 unsigned ValidLaneWidth,
15186 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15187 int Idx = ShuffV[i];
15188 if ((Idx >= 0 && Idx < LHSMaxIdx) || (Idx >= RHSMinIdx && Idx < RHSMaxIdx))
15190 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15201 SDLoc dl(OrigSToV);
15204 "Expecting a SCALAR_TO_VECTOR here");
15217 "Cannot produce a permuted scalar_to_vector for one element vector");
15219 unsigned ResultInElt = NumElts / 2;
15246 int NumElts = LHS.getValueType().getVectorNumElements();
15256 if (!Subtarget.hasDirectMove())
15275 if (SToVLHS || SToVRHS) {
15282 if (SToVLHS && SToVRHS &&
15289 int NumEltsOut = ShuffV.
size();
15294 unsigned ValidLaneWidth =
15296 LHS.getValueType().getScalarSizeInBits()
15298 RHS.getValueType().getScalarSizeInBits();
15302 int LHSMaxIdx = -1;
15303 int RHSMinIdx = -1;
15304 int RHSMaxIdx = -1;
15305 int HalfVec = LHS.getValueType().getVectorNumElements() / 2;
15317 LHSMaxIdx = NumEltsOut / NumEltsIn;
15320 SToVLHS = DAG.
getBitcast(LHS.getValueType(), SToVLHS);
15326 RHSMinIdx = NumEltsOut;
15327 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15330 SToVRHS = DAG.
getBitcast(RHS.getValueType(), SToVRHS);
15340 HalfVec, ValidLaneWidth, Subtarget);
15366 if (IsLittleEndian) {
15369 if (Mask[0] < NumElts)
15370 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15373 ShuffV[i] = (ShuffV[i - 1] + NumElts);
15378 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
15381 ShuffV[i] = (ShuffV[i + 1] + NumElts);
15386 if (Mask[0] < NumElts)
15387 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
15390 ShuffV[i] = ShuffV[i + 1] - NumElts;
15395 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15398 ShuffV[i] = ShuffV[i - 1] - NumElts;
15408 if (IsLittleEndian)
15417 DAGCombinerInfo &DCI)
const {
15419 "Not a reverse memop pattern!");
15424 auto I =
Mask.rbegin();
15425 auto E =
Mask.rend();
15427 for (;
I !=
E; ++
I) {
15444 if (!Subtarget.hasP9Vector())
15447 if(!IsElementReverse(SVN))
15450 if (LSBase->
getOpcode() == ISD::LOAD) {
15466 if (LSBase->
getOpcode() == ISD::STORE) {
15485 unsigned IntrinsicID =
15487 if (IntrinsicID == Intrinsic::ppc_stdcx)
15489 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15491 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15493 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15504 switch (
N->getOpcode()) {
15507 return combineADD(
N, DCI);
15533 return combineSHL(
N, DCI);
15535 return combineSRA(
N, DCI);
15537 return combineSRL(
N, DCI);
15539 return combineMUL(
N, DCI);
15542 return combineFMALike(
N, DCI);
15545 return N->getOperand(0);
15549 return N->getOperand(0);
15555 return N->getOperand(0);
15561 return DAGCombineExtBoolTrunc(
N, DCI);
15563 return combineTRUNCATE(
N, DCI);
15565 if (
SDValue CSCC = combineSetCC(
N, DCI))
15569 return DAGCombineTruncBoolExt(
N, DCI);
15572 return combineFPToIntToFP(
N, DCI);
15581 EVT Op1VT =
N->getOperand(1).getValueType();
15582 unsigned Opcode =
N->getOperand(1).getOpcode();
15586 SDValue Val = combineStoreFPToInt(
N, DCI);
15600 N->getOperand(1).getNode()->hasOneUse() &&
15601 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15602 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15617 if (Op1VT.
bitsGT(mVT)) {
15622 if (Op1VT == MVT::i64)
15659 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15660 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15667 EVT VT = LD->getValueType(0);
15674 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15675 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15686 auto ReplaceTwoFloatLoad = [&]() {
15687 if (VT != MVT::i64)
15702 if (!LD->hasNUsesOfValue(2, 0))
15705 auto UI = LD->use_begin();
15706 while (UI.getUse().getResNo() != 0) ++UI;
15708 while (UI.getUse().getResNo() != 0) ++UI;
15709 SDNode *RightShift = *UI;
15717 if (RightShift->getOpcode() !=
ISD::SRL ||
15719 RightShift->getConstantOperandVal(1) != 32 ||
15720 !RightShift->hasOneUse())
15723 SDNode *Trunc2 = *RightShift->use_begin();
15732 if (Bitcast->getOpcode() != ISD::BITCAST ||
15733 Bitcast->getValueType(0) != MVT::f32)
15735 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
15745 SDValue BasePtr = LD->getBasePtr();
15746 if (LD->isIndexed()) {
15748 "Non-pre-inc AM on PPC?");
15756 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
15757 LD->getPointerInfo(), LD->getAlign(),
15758 MMOFlags, LD->getAAInfo());
15764 LD->getPointerInfo().getWithOffset(4),
15767 if (LD->isIndexed()) {
15781 if (ReplaceTwoFloatLoad())
15784 EVT MemVT = LD->getMemoryVT();
15787 if (LD->isUnindexed() && VT.
isVector() &&
15790 !Subtarget.hasP8Vector() &&
15791 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
15792 VT == MVT::v4f32))) &&
15793 LD->getAlign() < ABIAlignment) {
15795 SDValue Chain = LD->getChain();
15824 MVT PermCntlTy, PermTy, LDTy;
15825 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
15826 : Intrinsic::ppc_altivec_lvsl;
15827 IntrLD = Intrinsic::ppc_altivec_lvx;
15828 IntrPerm = Intrinsic::ppc_altivec_vperm;
15829 PermCntlTy = MVT::v16i8;
15830 PermTy = MVT::v4i32;
15849 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
15853 BaseLoadOps, LDTy, BaseMMO);
15862 int IncValue = IncOffset;
15879 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
15883 ExtraLoadOps, LDTy, ExtraMMO);
15894 if (isLittleEndian)
15896 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
15899 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
15902 Perm = Subtarget.hasAltivec()
15903 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
15920 : Intrinsic::ppc_altivec_lvsl);
15921 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
15928 .
zext(
Add.getScalarValueSizeInBits()))) {
15929 SDNode *BasePtr =
Add->getOperand(0).getNode();
15930 for (
SDNode *U : BasePtr->uses()) {
15943 SDNode *BasePtr =
Add->getOperand(0).getNode();
15944 for (
SDNode *U : BasePtr->uses()) {
15967 (IID == Intrinsic::ppc_altivec_vmaxsw ||
15968 IID == Intrinsic::ppc_altivec_vmaxsh ||
15969 IID == Intrinsic::ppc_altivec_vmaxsb)) {
15985 V2.getOperand(1) == V1) {
16003 case Intrinsic::ppc_altivec_vsum4sbs:
16004 case Intrinsic::ppc_altivec_vsum4shs:
16005 case Intrinsic::ppc_altivec_vsum4ubs: {
16012 APInt APSplatBits, APSplatUndef;
16013 unsigned SplatBitSize;
16016 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16019 if (BVNIsConstantSplat && APSplatBits == 0)
16024 case Intrinsic::ppc_vsx_lxvw4x:
16025 case Intrinsic::ppc_vsx_lxvd2x:
16040 case Intrinsic::ppc_vsx_stxvw4x:
16041 case Intrinsic::ppc_vsx_stxvd2x:
16050 bool Is64BitBswapOn64BitTgt =
16051 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16053 N->getOperand(0).hasOneUse();
16054 if (IsSingleUseNormalLd &&
16055 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16056 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16067 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16068 MVT::i64 : MVT::i32, MVT::Other),
16069 Ops, LD->getMemoryVT(), LD->getMemOperand());
16073 if (
N->getValueType(0) == MVT::i16)
16090 !IsSingleUseNormalLd)
16095 if (!LD->isSimple())
16097 SDValue BasePtr = LD->getBasePtr();
16099 LD->getPointerInfo(), LD->getAlign());
16104 LD->getMemOperand(), 4, 4);
16114 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16123 if (!
N->getOperand(0).hasOneUse() &&
16124 !
N->getOperand(1).hasOneUse() &&
16125 !
N->getOperand(2).hasOneUse()) {
16128 SDNode *VCMPrecNode =
nullptr;
16134 UI->getOperand(1) ==
N->getOperand(1) &&
16135 UI->getOperand(2) ==
N->getOperand(2) &&
16136 UI->getOperand(0) ==
N->getOperand(0)) {
16149 SDNode *FlagUser =
nullptr;
16151 FlagUser ==
nullptr; ++UI) {
16152 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16165 return SDValue(VCMPrecNode, 0);
16188 if (!RHSAPInt.isIntN(64))
16191 unsigned Val = RHSAPInt.getZExtValue();
16192 auto isImpossibleCompare = [&]() {
16195 if (Val != 0 && Val != 1) {
16197 return N->getOperand(0);
16199 return DAG.
getNode(ISD::BR, dl, MVT::Other,
16200 N->getOperand(0),
N->getOperand(4));
16205 unsigned StoreWidth = 0;
16208 if (
SDValue Impossible = isImpossibleCompare())
16220 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
16225 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16226 MemNode->getMemoryVT(), MemNode->getMemOperand());
16230 if (
N->getOperand(0) == LHS.getValue(1))
16249 assert(isDot &&
"Can't compare against a vector result!");
16251 if (
SDValue Impossible = isImpossibleCompare())
16254 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16261 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
16290 return DAGCombineBuildVector(
N, DCI);
16301 EVT VT =
N->getValueType(0);
16302 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16304 if ((VT != MVT::i32 && VT != MVT::i64) ||
16312 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16332 const APInt &DemandedElts,
16334 unsigned Depth)
const {
16336 switch (
Op.getOpcode()) {
16341 Known.
Zero = 0xFFFF0000;
16347 case Intrinsic::ppc_altivec_vcmpbfp_p:
16348 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16349 case Intrinsic::ppc_altivec_vcmpequb_p:
16350 case Intrinsic::ppc_altivec_vcmpequh_p:
16351 case Intrinsic::ppc_altivec_vcmpequw_p:
16352 case Intrinsic::ppc_altivec_vcmpequd_p:
16353 case Intrinsic::ppc_altivec_vcmpequq_p:
16354 case Intrinsic::ppc_altivec_vcmpgefp_p:
16355 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16356 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16357 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16358 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16359 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16360 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16361 case Intrinsic::ppc_altivec_vcmpgtub_p:
16362 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16363 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16364 case Intrinsic::ppc_altivec_vcmpgtud_p:
16365 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16375 case Intrinsic::ppc_load2r:
16377 Known.
Zero = 0xFFFF0000;
16407 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16416 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16418 LoopSize +=
TII->getInstSizeInBytes(J);
16423 if (LoopSize > 16 && LoopSize <= 32)
16437 if (Constraint.
size() == 1) {
16438 switch (Constraint[0]) {
16456 }
else if (Constraint ==
"wc") {
16458 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16459 Constraint ==
"wf" || Constraint ==
"ws" ||
16460 Constraint ==
"wi" || Constraint ==
"ww") {
16473 Value *CallOperandVal =
info.CallOperandVal;
16476 if (!CallOperandVal)
16481 if (
StringRef(constraint) ==
"wc" && type->isIntegerTy(1))
16483 else if ((
StringRef(constraint) ==
"wa" ||
16486 type->isVectorTy())
16488 else if (
StringRef(constraint) ==
"wi" && type->isIntegerTy(64))
16490 else if (
StringRef(constraint) ==
"ws" && type->isDoubleTy())
16492 else if (
StringRef(constraint) ==
"ww" && type->isFloatTy())
16495 switch (*constraint) {
16500 if (type->isIntegerTy())
16504 if (type->isFloatTy())
16508 if (type->isDoubleTy())
16512 if (type->isVectorTy())
16525std::pair<unsigned, const TargetRegisterClass *>
16529 if (Constraint.
size() == 1) {
16531 switch (Constraint[0]) {
16533 if (VT == MVT::i64 && Subtarget.
isPPC64())
16534 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16535 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16537 if (VT == MVT::i64 && Subtarget.
isPPC64())
16538 return std::make_pair(0U, &PPC::G8RCRegClass);
16539 return std::make_pair(0U, &PPC::GPRCRegClass);
16545 if (Subtarget.hasSPE()) {
16546 if (VT == MVT::f32 || VT == MVT::i32)
16547 return std::make_pair(0U, &PPC::GPRCRegClass);
16548 if (VT == MVT::f64 || VT == MVT::i64)
16549 return std::make_pair(0U, &PPC::SPERCRegClass);
16551 if (VT == MVT::f32 || VT == MVT::i32)
16552 return std::make_pair(0U, &PPC::F4RCRegClass);
16553 if (VT == MVT::f64 || VT == MVT::i64)
16554 return std::make_pair(0U, &PPC::F8RCRegClass);
16558 if (Subtarget.hasAltivec() && VT.
isVector())
16559 return std::make_pair(0U, &PPC::VRRCRegClass);
16560 else if (Subtarget.hasVSX())
16562 return std::make_pair(0U, &PPC::VFRCRegClass);
16565 return std::make_pair(0U, &PPC::CRRCRegClass);
16567 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16569 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16570 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16571 Constraint ==
"wf" || Constraint ==
"wi") &&
16572 Subtarget.hasVSX()) {
16576 return std::make_pair(0U, &PPC::VSRCRegClass);
16577 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16578 return std::make_pair(0U, &PPC::VSSRCRegClass);
16579 return std::make_pair(0U, &PPC::VSFRCRegClass);
16580 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16581 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16582 return std::make_pair(0U, &PPC::VSSRCRegClass);
16584 return std::make_pair(0U, &PPC::VSFRCRegClass);
16585 }
else if (Constraint ==
"lr") {
16586 if (VT == MVT::i64)
16587 return std::make_pair(0U, &PPC::LR8RCRegClass);
16589 return std::make_pair(0U, &PPC::LRRCRegClass);
16594 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16598 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16599 int VSNum = atoi(Constraint.
data() + 3);
16600 assert(VSNum >= 0 && VSNum <= 63 &&
16601 "Attempted to access a vsr out of range");
16603 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16604 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16609 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16610 int RegNum = atoi(Constraint.
data() + 2);
16611 if (RegNum > 31 || RegNum < 0)
16613 if (VT == MVT::f32 || VT == MVT::i32)
16614 return Subtarget.hasSPE()
16615 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16616 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16617 if (VT == MVT::f64 || VT == MVT::i64)
16618 return Subtarget.hasSPE()
16619 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16620 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16624 std::pair<unsigned, const TargetRegisterClass *> R =
16633 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16634 PPC::GPRCRegClass.contains(R.first))
16635 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16636 PPC::sub_32, &PPC::G8RCRegClass),
16637 &PPC::G8RCRegClass);
16640 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16641 R.first = PPC::CR0;
16642 R.second = &PPC::CRRCRegClass;
16646 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16647 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16648 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16649 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16650 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16651 "default AIX AltiVec ABI and cannot be used\n";
16660 std::string &Constraint,
16661 std::vector<SDValue>&Ops,
16666 if (Constraint.length() > 1)
return;
16668 char Letter = Constraint[0];
16683 EVT TCVT = MVT::i64;
16724 if (Result.getNode()) {
16725 Ops.push_back(Result);
16736 if (
I.getNumOperands() <= 1)
16741 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
16742 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
16745 if (
I.hasMetadata(
"annotation")) {
16746 MDNode *MDN =
I.getMetadata(
"annotation");
16763 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
16775 switch (AM.
Scale) {
16812 bool isPPC64 = Subtarget.
isPPC64();
16824 isPPC64 ? MVT::i64 : MVT::i32);
16831 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
16846 bool isPPC64 = PtrVT == MVT::i64;
16852 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
16854 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
16868 bool isPPC64 = Subtarget.
isPPC64();
16920 unsigned Intrinsic)
const {
16921 switch (Intrinsic) {
16922 case Intrinsic::ppc_atomicrmw_xchg_i128:
16923 case Intrinsic::ppc_atomicrmw_add_i128:
16924 case Intrinsic::ppc_atomicrmw_sub_i128:
16925 case Intrinsic::ppc_atomicrmw_nand_i128:
16926 case Intrinsic::ppc_atomicrmw_and_i128:
16927 case Intrinsic::ppc_atomicrmw_or_i128:
16928 case Intrinsic::ppc_atomicrmw_xor_i128:
16929 case Intrinsic::ppc_cmpxchg_i128:
16931 Info.memVT = MVT::i128;
16932 Info.ptrVal =
I.getArgOperand(0);
16934 Info.align =
Align(16);
16938 case Intrinsic::ppc_atomic_load_i128:
16940 Info.memVT = MVT::i128;
16941 Info.ptrVal =
I.getArgOperand(0);
16943 Info.align =
Align(16);
16946 case Intrinsic::ppc_atomic_store_i128:
16948 Info.memVT = MVT::i128;
16949 Info.ptrVal =
I.getArgOperand(2);
16951 Info.align =
Align(16);
16954 case Intrinsic::ppc_altivec_lvx:
16955 case Intrinsic::ppc_altivec_lvxl:
16956 case Intrinsic::ppc_altivec_lvebx:
16957 case Intrinsic::ppc_altivec_lvehx:
16958 case Intrinsic::ppc_altivec_lvewx:
16959 case Intrinsic::ppc_vsx_lxvd2x:
16960 case Intrinsic::ppc_vsx_lxvw4x:
16961 case Intrinsic::ppc_vsx_lxvd2x_be:
16962 case Intrinsic::ppc_vsx_lxvw4x_be:
16963 case Intrinsic::ppc_vsx_lxvl:
16964 case Intrinsic::ppc_vsx_lxvll: {
16966 switch (Intrinsic) {
16967 case Intrinsic::ppc_altivec_lvebx:
16970 case Intrinsic::ppc_altivec_lvehx:
16973 case Intrinsic::ppc_altivec_lvewx:
16976 case Intrinsic::ppc_vsx_lxvd2x:
16977 case Intrinsic::ppc_vsx_lxvd2x_be:
16987 Info.ptrVal =
I.getArgOperand(0);
16990 Info.align =
Align(1);
16994 case Intrinsic::ppc_altivec_stvx:
16995 case Intrinsic::ppc_altivec_stvxl:
16996 case Intrinsic::ppc_altivec_stvebx:
16997 case Intrinsic::ppc_altivec_stvehx:
16998 case Intrinsic::ppc_altivec_stvewx:
16999 case Intrinsic::ppc_vsx_stxvd2x:
17000 case Intrinsic::ppc_vsx_stxvw4x:
17001 case Intrinsic::ppc_vsx_stxvd2x_be:
17002 case Intrinsic::ppc_vsx_stxvw4x_be:
17003 case Intrinsic::ppc_vsx_stxvl:
17004 case Intrinsic::ppc_vsx_stxvll: {
17006 switch (Intrinsic) {
17007 case Intrinsic::ppc_altivec_stvebx:
17010 case Intrinsic::ppc_altivec_stvehx:
17013 case Intrinsic::ppc_altivec_stvewx:
17016 case Intrinsic::ppc_vsx_stxvd2x:
17017 case Intrinsic::ppc_vsx_stxvd2x_be:
17027 Info.ptrVal =
I.getArgOperand(1);
17030 Info.align =
Align(1);
17034 case Intrinsic::ppc_stdcx:
17035 case Intrinsic::ppc_stwcx:
17036 case Intrinsic::ppc_sthcx:
17037 case Intrinsic::ppc_stbcx: {
17039 auto Alignment =
Align(8);
17040 switch (Intrinsic) {
17041 case Intrinsic::ppc_stdcx:
17044 case Intrinsic::ppc_stwcx:
17046 Alignment =
Align(4);
17048 case Intrinsic::ppc_sthcx:
17050 Alignment =
Align(2);
17052 case Intrinsic::ppc_stbcx:
17054 Alignment =
Align(1);
17059 Info.ptrVal =
I.getArgOperand(0);
17061 Info.align = Alignment;
17079 if (Subtarget.hasAltivec() &&
Op.size() >= 16 &&
17081 ((
Op.isMemset() && Subtarget.hasVSX()) || Subtarget.hasP8Vector())))
17096 assert(Ty->isIntegerTy());
17098 unsigned BitSize = Ty->getPrimitiveSizeInBits();
17099 return !(BitSize == 0 || BitSize > 64);
17107 return NumBits1 == 64 && NumBits2 == 32;
17115 return NumBits1 == 64 && NumBits2 == 32;
17122 EVT MemVT = LD->getMemoryVT();
17123 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17124 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17140 "invalid fpext types");
17142 if (DestVT == MVT::f128)
17157 unsigned *
Fast)
const {
17171 !Subtarget.allowsUnalignedFPAccess())
17175 if (Subtarget.hasVSX()) {
17176 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17177 VT != MVT::v4f32 && VT != MVT::v4i32)
17184 if (VT == MVT::ppcf128)
17199 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17207 int64_t Imm = ConstNode->getSExtValue();
17228 if (Subtarget.hasSPE())
17230 switch (Ty->getScalarType()->getTypeID()) {
17235 return Subtarget.hasP9Vector();
17243 if (!
I->hasOneUse())
17247 assert(
User &&
"A single use instruction with no uses.");
17249 switch (
I->getOpcode()) {
17250 case Instruction::FMul: {
17252 if (
User->getOpcode() != Instruction::FSub &&
17253 User->getOpcode() != Instruction::FAdd)
17266 case Instruction::Load: {
17279 if (
User->getOpcode() != Instruction::Store)
17299 static const MCPhysReg ScratchRegs[] = {
17300 PPC::X12, PPC::LR8, PPC::CTR8, 0
17303 return ScratchRegs;
17307 const Constant *PersonalityFn)
const {
17308 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17312 const Constant *PersonalityFn)
const {
17313 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17318 EVT VT ,
unsigned DefinedValues)
const {
17319 if (VT == MVT::v2i64)
17320 return Subtarget.hasDirectMove();
17322 if (Subtarget.hasVSX())
17356 bool LegalOps,
bool OptForSize,
17358 unsigned Depth)
const {
17362 unsigned Opc =
Op.getOpcode();
17363 EVT VT =
Op.getValueType();
17388 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17392 N0Cost,
Depth + 1);
17396 N1Cost,
Depth + 1);
17398 if (NegN0 && N0Cost <= N1Cost) {
17399 Cost = std::min(N0Cost, N2Cost);
17400 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17401 }
else if (NegN1) {
17402 Cost = std::min(N1Cost, N2Cost);
17403 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17446 bool ForCodeSize)
const {
17447 if (!VT.
isSimple() || !Subtarget.hasVSX())
17457 if (Subtarget.hasPrefixInstrs()) {
17462 APSInt IntResult(16,
false);
17467 if (IsExact && IntResult <= 15 && IntResult >= -16)
17469 return Imm.isZero();
17472 return Imm.isPosZero();
17484 unsigned Opcode =
N->getOpcode();
17485 unsigned TargetOpcode;
17504 if (Mask->getZExtValue() == OpSizeInBits - 1)
17510SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17516 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17519 N->getValueType(0) != MVT::i64)
17534 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17540SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17547SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17566 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17568 Op.getValueType() != MVT::i64)
17572 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17573 Cmp.getOperand(0).getValueType() != MVT::i64)
17577 int64_t NegConstant = 0 -
Constant->getSExtValue();
17586 bool LHSHasPattern = isZextOfCompareWithConstant(LHS);
17587 bool RHSHasPattern = isZextOfCompareWithConstant(RHS);
17590 if (LHSHasPattern && !RHSHasPattern)
17592 else if (!LHSHasPattern && !RHSHasPattern)
17597 SDValue Cmp = RHS.getOperand(0);
17598 SDValue Z = Cmp.getOperand(0);
17600 int64_t NegConstant = 0 -
Constant->getSExtValue();
17613 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17628 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17665 if (!GSDN || !ConstNode)
17685SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17705 DAGCombinerInfo &DCI)
const {
17707 if (Subtarget.useCRBits()) {
17709 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17710 return CRTruncValue;
17717 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
17720 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17730 EltToExtract = EltToExtract ? 0 : 1;
17740 return DCI.DAG.getNode(
17742 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
17747SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17751 if (!ConstOpOrElement)
17759 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
17782 return IsAddOne && IsNeg ? VT.
isVector() :
true;
17786 EVT VT =
N->getValueType(0);
17793 if ((MulAmtAbs - 1).isPowerOf2()) {
17797 if (!IsProfitable(IsNeg,
true, VT))
17810 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
17814 if (!IsProfitable(IsNeg,
false, VT))
17835 DAGCombinerInfo &DCI)
const {
17840 EVT VT =
N->getValueType(0);
17843 unsigned Opc =
N->getOpcode();
17845 bool LegalOps = !DCI.isBeforeLegalizeOps();
17853 if (!Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
17869bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
17899bool PPCTargetLowering::
17900isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
17905 if (CI->getBitWidth() > 64)
17907 int64_t ConstVal = CI->getZExtValue();
17909 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
17918PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
17924 if ((Flags & FlagSet) == FlagSet)
17927 if ((Flags & FlagSet) == FlagSet)
17930 if ((Flags & FlagSet) == FlagSet)
17933 if ((Flags & FlagSet) == FlagSet)
17954 if ((FrameIndexAlign % 4) != 0)
17955 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
17956 if ((FrameIndexAlign % 16) != 0)
17957 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
17961 if ((FrameIndexAlign % 4) == 0)
17963 if ((FrameIndexAlign % 16) == 0)
17976 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
17977 if ((Imm & 0x3) == 0)
17979 if ((Imm & 0xf) == 0)
17985 const APInt &ConstImm = CN->getAPIntValue();
18004 const APInt &ConstImm = CN->getAPIntValue();
18035unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18040 if (!Subtarget.hasP9Vector())
18044 if (Subtarget.hasPrefixInstrs())
18047 if (Subtarget.hasSPE())
18056 unsigned ParentOp = Parent->
getOpcode();
18060 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
18061 SDValue IntrinOp = (ID == Intrinsic::ppc_vsx_lxvp)
18073 if (LSB->isIndexed())
18079 assert(MN &&
"Parent should be a MemSDNode!");
18084 "Not expecting scalar integers larger than 16 bytes!");
18087 else if (
Size == 32)
18094 else if (
Size == 256) {
18095 assert(Subtarget.pairedVectorMemops() &&
18096 "256-bit vectors are only available when paired vector memops is "
18104 else if (MemVT == MVT::f128 || MemVT.
isVector())
18135 FlagSet &= ~PPC::MOF_NoExt;
18140 bool IsNonP1034BitConst =
18144 IsNonP1034BitConst)
18157 int16_t ForceXFormImm = 0;
18172 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18188 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18194 if (PartVT == MVT::f64 &&
18195 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18197 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
18204SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18208 EVT RetVT =
Op.getValueType();
18216 EVT ArgVT =
N.getValueType();
18221 Entry.IsZExt = !Entry.IsSExt;
18222 Args.push_back(Entry);
18230 (RetTy ==
F.getReturnType() ||
F.getReturnType()->
isVoidTy());
18243SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18244 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18246 if (
Op.getValueType() == MVT::f32)
18247 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18249 if (
Op.getValueType() == MVT::f64)
18250 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18255bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18257 return isLowringToMASSSafe(
Op) && Flags.hasNoSignedZeros() &&
18258 Flags.hasNoNaNs() && Flags.hasNoInfs();
18261bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18262 return Op.getNode()->getFlags().hasApproximateFuncs();
18265bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18269SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18270 const char *LibCallFloatName,
18271 const char *LibCallDoubleNameFinite,
18272 const char *LibCallFloatNameFinite,
18275 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18278 if (!isLowringToMASSFiniteSafe(
Op))
18279 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18282 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18283 LibCallDoubleNameFinite,
Op, DAG);
18287 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18288 "__xl_powf_finite",
Op, DAG);
18292 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18293 "__xl_sinf_finite",
Op, DAG);
18297 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18298 "__xl_cosf_finite",
Op, DAG);
18302 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18303 "__xl_logf_finite",
Op, DAG);
18307 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18308 "__xl_log10f_finite",
Op, DAG);
18312 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18313 "__xl_expf_finite",
Op, DAG);
18338 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18350 "Must be using PC-Relative calls when a valid PC-Relative node is "
18385 Base =
N.getOperand(0);
18393 EVT CNType = CN->getValueType(0);
18394 uint64_t CNImm = CN->getZExtValue();
18405 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
18407 int32_t
Addr = (int32_t)CNImm;
18412 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18428 unsigned Opcode =
N.getOpcode();
18467 bool IsVarArg)
const {
18477 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18511 return Intrinsic::ppc_atomicrmw_xchg_i128;
18513 return Intrinsic::ppc_atomicrmw_add_i128;
18515 return Intrinsic::ppc_atomicrmw_sub_i128;
18517 return Intrinsic::ppc_atomicrmw_and_i128;
18519 return Intrinsic::ppc_atomicrmw_or_i128;
18521 return Intrinsic::ppc_atomicrmw_xor_i128;
18523 return Intrinsic::ppc_atomicrmw_nand_i128;
18531 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
18533 assert(ValTy->getPrimitiveSizeInBits() == 128);
18537 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
18539 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
18542 Value *LoHi = Builder.CreateCall(RMW, {
Addr, IncrLo, IncrHi});
18543 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
18544 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
18545 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
18546 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
18547 return Builder.CreateOr(
18555 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
18557 assert(ValTy->getPrimitiveSizeInBits() == 128);
18561 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
18563 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
18564 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
18566 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
18571 Builder.CreateCall(IntCmpXchg, {
Addr, CmpLo, CmpHi, NewLo, NewHi});
18573 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
18574 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
18575 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
18576 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
18577 return Builder.CreateOr(
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDNode *N, SelectionDAG &DAG)
static const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
unsigned const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
Module.h This file contains the declarations for the Module class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const char LLVMTargetMachineRef TM
pre isel intrinsic Pre ISel Intrinsic Lowering
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysis::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysis::AdvisorMode::Development, "development", "for training")))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
This is an SDNode representing atomic operations.
This class holds the attributes for a function, its return value, and its parameters.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
const Function & getFunction() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
@ Kind_RegDefEarlyClobber
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
static unsigned getKind(unsigned Flags)
const BasicBlock * getParent() const
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineInstr - Allocate a new MachineInstr.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
uint64_t getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
const MCContext & getContext() const
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, uint64_t Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize Fixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt64Ty(LLVMContext &C)
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_GOT_FLAG
MO_GOT_FLAG - If this bit is set the symbol reference is to be computed via the GOT.
@ MO_PLT
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local-exec TLS model on 32-bit AIX, produces a call to ....
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
bool isa_and_nonnull(const Y &Val)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg If BaseGV is null...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)